From c02aefeb5c36ca9aca3df7e46bfc7b0b3a085a94 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 30 Nov 2022 19:52:09 +0900 Subject: [PATCH 01/29] chore: bump sinon from 14.0.2 to 15.0.0 (#5121) Bumps [sinon](https://github.com/sinonjs/sinon) from 14.0.2 to 15.0.0. - [Release notes](https://github.com/sinonjs/sinon/releases) - [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md) - [Commits](https://github.com/sinonjs/sinon/compare/v14.0.2...v15.0.0) --- updated-dependencies: - dependency-name: sinon dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 09e0b12120..c8fc3c53da 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "husky": "^8.0.1", "lint-staged": "^13.0.3", "mocha": "^10.0.0", - "sinon": "^14.0.0" + "sinon": "^15.0.0" }, "engines": { "node": ">=14" From 0fe24a44fee0763c4113330e806bd7ce9aa230b2 Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Sat, 10 Dec 2022 17:30:37 +0800 Subject: [PATCH 02/29] fix(post): skip before_post_render and after_post_render on non-posts (#5118) --- lib/hexo/post.js | 21 +++++++++++++++++++++ test/scripts/hexo/post.js | 10 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/hexo/post.js b/lib/hexo/post.js index 117669e5ff..4a4e23caab 100644 --- a/lib/hexo/post.js +++ b/lib/hexo/post.js @@ -376,6 +376,27 @@ class Post { return Promise.reject(new Error('No input file or string!')).asCallback(callback); } + // Files like js and css are also processed by this function, but they do not require preprocessing like markdown + // data.source does not exist when tag plugins call the markdown renderer + const isPost = !data.source || ['html', 'htm'].includes(ctx.render.getOutput(data.source)); + + if (!isPost) { + return promise.then(content => { + data.content = content; + ctx.log.debug('Rendering file: %s', magenta(source)); + + return ctx.render.render({ + text: data.content, + path: source, + engine: data.engine, + toString: true + }); + }).then(content => { + data.content = content; + return data; + }).asCallback(callback); + } + // disable Nunjucks when the renderer specify that. let disableNunjucks = ext && ctx.render.renderer.get(ext) && !!ctx.render.renderer.get(ext).disableNunjucks; diff --git a/test/scripts/hexo/post.js b/test/scripts/hexo/post.js index 8927708bf4..e2ab65205c 100644 --- a/test/scripts/hexo/post.js +++ b/test/scripts/hexo/post.js @@ -685,6 +685,16 @@ describe('Post', () => { await unlink(path); }); + it('render() - skip js', async () => { + const content = 'let a = "{{ 1 + 1 }}"'; + + const data = await post.render(null, { + content, + source: 'render_test.js' + }); + data.content.trim().should.eql(content); + }); + it('render() - toString', async () => { const content = 'foo: 1'; From 6127df43ba933b68003b59165d66e3612dd8b79f Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Sat, 10 Dec 2022 17:31:30 +0800 Subject: [PATCH 03/29] refactor: prepare for migration to typescript (#5094) --- lib/extend/index.js | 24 ++++++++++++++---------- lib/hexo/scaffold.js | 2 +- lib/models/index.js | 24 ++++++++++++++---------- lib/plugins/console/generate.js | 2 +- lib/plugins/console/list/index.js | 11 ++++++----- lib/plugins/helper/number_format.js | 4 ++-- lib/plugins/tag/img.js | 2 +- 7 files changed, 39 insertions(+), 30 deletions(-) diff --git a/lib/extend/index.js b/lib/extend/index.js index 5e4eb37b28..fded0037cf 100644 --- a/lib/extend/index.js +++ b/lib/extend/index.js @@ -1,12 +1,16 @@ 'use strict'; -exports.Console = require('./console'); -exports.Deployer = require('./deployer'); -exports.Filter = require('./filter'); -exports.Generator = require('./generator'); -exports.Helper = require('./helper'); -exports.Injector = require('./injector'); -exports.Migrator = require('./migrator'); -exports.Processor = require('./processor'); -exports.Renderer = require('./renderer'); -exports.Tag = require('./tag'); +const Console = require('./console'); +const Deployer = require('./deployer'); +const Filter = require('./filter'); +const Generator = require('./generator'); +const Helper = require('./helper'); +const Injector = require('./injector'); +const Migrator = require('./migrator'); +const Processor = require('./processor'); +const Renderer = require('./renderer'); +const Tag = require('./tag'); + +module.exports = { + Console, Deployer, Filter, Generator, Helper, Injector, Migrator, Processor, Renderer, Tag +}; diff --git a/lib/hexo/scaffold.js b/lib/hexo/scaffold.js index f1e83c0cf1..c1d59f2aa2 100644 --- a/lib/hexo/scaffold.js +++ b/lib/hexo/scaffold.js @@ -26,7 +26,7 @@ class Scaffold { if (!exist) return []; return listDir(scaffoldDir, { - ignoreFilesRegex: /^_|\/_/ + ignorePattern: /^_|\/_/ }); }).map(item => ({ name: item.substring(0, item.length - extname(item).length), diff --git a/lib/models/index.js b/lib/models/index.js index f52d915e1b..18ae185867 100644 --- a/lib/models/index.js +++ b/lib/models/index.js @@ -1,12 +1,16 @@ 'use strict'; -exports.Asset = require('./asset'); -exports.Cache = require('./cache'); -exports.Category = require('./category'); -exports.Data = require('./data'); -exports.Page = require('./page'); -exports.Post = require('./post'); -exports.PostAsset = require('./post_asset'); -exports.PostCategory = require('./post_category'); -exports.PostTag = require('./post_tag'); -exports.Tag = require('./tag'); +const Asset = require('./asset'); +const Cache = require('./cache'); +const Category = require('./category'); +const Data = require('./data'); +const Page = require('./page'); +const Post = require('./post'); +const PostAsset = require('./post_asset'); +const PostCategory = require('./post_category'); +const PostTag = require('./post_tag'); +const Tag = require('./tag'); + +module.exports = { + Asset, Cache, Category, Data, Page, Post, PostAsset, PostCategory, PostTag, Tag +}; diff --git a/lib/plugins/console/generate.js b/lib/plugins/console/generate.js index a95abb0e15..261ba40132 100644 --- a/lib/plugins/console/generate.js +++ b/lib/plugins/console/generate.js @@ -133,7 +133,7 @@ class Generater { // Check the public folder return stat(publicDir).then(stats => { if (!stats.isDirectory()) { - throw new Error('%s is not a directory', magenta(tildify(publicDir))); + throw new Error(`${magenta(tildify(publicDir))} is not a directory`); } }).catch(err => { // Create public folder if not exists diff --git a/lib/plugins/console/list/index.js b/lib/plugins/console/list/index.js index 4ab6fba1d0..debab88983 100644 --- a/lib/plugins/console/list/index.js +++ b/lib/plugins/console/list/index.js @@ -1,13 +1,14 @@ 'use strict'; const abbrev = require('abbrev'); +const page = require('./page'); +const post = require('./post'); +const route = require('./route'); +const tag = require('./tag'); +const category = require('./category'); const store = { - page: require('./page'), - post: require('./post'), - route: require('./route'), - tag: require('./tag'), - category: require('./category') + page, post, route, tag, category }; const alias = abbrev(Object.keys(store)); diff --git a/lib/plugins/helper/number_format.js b/lib/plugins/helper/number_format.js index 7a1495f67f..c6c2c0985d 100644 --- a/lib/plugins/helper/number_format.js +++ b/lib/plugins/helper/number_format.js @@ -30,7 +30,7 @@ function numberFormatHelper(num, options = {}) { const afterLast = after[precision]; const last = parseInt(after[precision - 1], 10); - afterResult = after.substring(0, precision - 1) + (afterLast < 5 ? last : last + 1); + afterResult = after.substring(0, precision - 1) + (Number(afterLast) < 5 ? last : last + 1); } else { afterResult = after; for (let i = 0, len = precision - afterLength; i < len; i++) { @@ -39,7 +39,7 @@ function numberFormatHelper(num, options = {}) { } after = afterResult; - } else if (precision === 0 || precision === '0') { + } else if (precision === 0) { after = ''; } diff --git a/lib/plugins/tag/img.js b/lib/plugins/tag/img.js index 0a1ef7073e..e474d27b32 100644 --- a/lib/plugins/tag/img.js +++ b/lib/plugins/tag/img.js @@ -14,7 +14,7 @@ const rMetaSingleQuote = /'?([^']+)?'?/; */ module.exports = ctx => { - return function imgTag(args, content) { + return function imgTag(args) { const classes = []; let src, width, height, title, alt; From 40df92259a8df241f2676c325c94144455568ae3 Mon Sep 17 00:00:00 2001 From: Sukka Date: Sat, 10 Dec 2022 17:31:48 +0800 Subject: [PATCH 04/29] test(benchmark): update hexo-many-posts repo (#5128) --- test/benchmark.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/benchmark.js b/test/benchmark.js index 045b13bee2..f22a830605 100644 --- a/test/benchmark.js +++ b/test/benchmark.js @@ -168,7 +168,7 @@ async function init() { log.info('Setting up a dummy hexo site with 500 posts'); await gitClone('https://github.com/hexojs/hexo-theme-unit-test.git', testDir); await gitClone('https://github.com/hexojs/hexo-theme-landscape', resolve(testDir, 'themes', 'landscape')); - await gitClone('https://github.com/SukkaLab/hexo-many-posts.git', resolve(testDir, 'source', '_posts', 'hexo-many-posts')); + await gitClone('https://github.com/hexojs/hexo-many-posts.git', resolve(testDir, 'source', '_posts', 'hexo-many-posts')); } log.info('Installing dependencies'); From d485ebd4ed88d539255caeb0d925d7bb81ada537 Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Wed, 14 Dec 2022 22:36:08 +0800 Subject: [PATCH 05/29] refactor highlight: add extend api for syntax highlight (#5095) --- lib/extend/index.js | 3 +- lib/extend/syntax_highlight.js | 29 ++++ lib/hexo/default_config.js | 3 +- lib/hexo/index.js | 4 +- lib/hexo/post.js | 2 +- .../before_post_render/backtick_code_block.js | 132 +++++++----------- .../filter/before_post_render/index.js | 2 +- lib/plugins/highlight/highlight.js | 44 ++++++ lib/plugins/highlight/index.js | 8 ++ lib/plugins/highlight/prism.js | 26 ++++ lib/plugins/tag/code.js | 75 +--------- lib/plugins/tag/include_code.js | 41 +----- test/scripts/filters/backtick_code_block.js | 13 +- test/scripts/hexo/load_config.js | 2 +- test/scripts/hexo/post.js | 19 +-- test/scripts/tags/code.js | 13 +- test/scripts/tags/include_code.js | 12 +- 17 files changed, 203 insertions(+), 225 deletions(-) create mode 100644 lib/extend/syntax_highlight.js create mode 100644 lib/plugins/highlight/highlight.js create mode 100644 lib/plugins/highlight/index.js create mode 100644 lib/plugins/highlight/prism.js diff --git a/lib/extend/index.js b/lib/extend/index.js index fded0037cf..f4ddd1a2e5 100644 --- a/lib/extend/index.js +++ b/lib/extend/index.js @@ -5,6 +5,7 @@ const Deployer = require('./deployer'); const Filter = require('./filter'); const Generator = require('./generator'); const Helper = require('./helper'); +const Highlight = require('./syntax_highlight'); const Injector = require('./injector'); const Migrator = require('./migrator'); const Processor = require('./processor'); @@ -12,5 +13,5 @@ const Renderer = require('./renderer'); const Tag = require('./tag'); module.exports = { - Console, Deployer, Filter, Generator, Helper, Injector, Migrator, Processor, Renderer, Tag + Console, Deployer, Filter, Generator, Helper, Highlight, Injector, Migrator, Processor, Renderer, Tag }; diff --git a/lib/extend/syntax_highlight.js b/lib/extend/syntax_highlight.js new file mode 100644 index 0000000000..56d83ba2a8 --- /dev/null +++ b/lib/extend/syntax_highlight.js @@ -0,0 +1,29 @@ +'use strict'; + +class SyntaxHighlight { + constructor() { + this.store = {}; + } + + register(name, fn) { + if (typeof fn !== 'function') throw new TypeError('fn must be a function'); + + this.store[name] = fn; + } + + query(name) { + return name && this.store[name]; + } + + exec(name, options) { + const fn = this.store[name]; + + if (!fn) throw new TypeError(`syntax highlighter ${name} is not registered`); + const ctx = options.context; + const args = options.args || []; + + return Reflect.apply(fn, ctx, args); + } +} + +module.exports = SyntaxHighlight; diff --git a/lib/hexo/default_config.js b/lib/hexo/default_config.js index 07c0d5ed01..3c887a2400 100644 --- a/lib/hexo/default_config.js +++ b/lib/hexo/default_config.js @@ -40,8 +40,8 @@ module.exports = { post_asset_folder: false, relative_link: false, future: true, + syntax_highlighter: 'highlight.js', highlight: { - enable: true, auto_detect: false, line_number: true, tab_replace: '', @@ -51,7 +51,6 @@ module.exports = { hljs: false }, prismjs: { - enable: false, preprocess: true, line_number: true, tab_replace: '' diff --git a/lib/hexo/index.js b/lib/hexo/index.js index 41d9ffa50b..8f6fe53344 100644 --- a/lib/hexo/index.js +++ b/lib/hexo/index.js @@ -11,7 +11,7 @@ const Module = require('module'); const { runInThisContext } = require('vm'); const { version } = require('../../package.json'); const { logger } = require('hexo-log'); -const { Console, Deployer, Filter, Generator, Helper, Injector, Migrator, Processor, Renderer, Tag } = require('../extend'); +const { Console, Deployer, Filter, Generator, Helper, Highlight, Injector, Migrator, Processor, Renderer, Tag } = require('../extend'); const Render = require('./render'); const registerModels = require('./register_models'); const Post = require('./post'); @@ -123,6 +123,7 @@ class Hexo extends EventEmitter { filter: new Filter(), generator: new Generator(), helper: new Helper(), + highlight: new Highlight(), injector: new Injector(), migrator: new Migrator(), processor: new Processor(), @@ -224,6 +225,7 @@ class Hexo extends EventEmitter { require('../plugins/filter')(this); require('../plugins/generator')(this); require('../plugins/helper')(this); + require('../plugins/highlight')(this); require('../plugins/injector')(this); require('../plugins/processor')(this); require('../plugins/renderer')(this); diff --git a/lib/hexo/post.js b/lib/hexo/post.js index 4a4e23caab..2b91d56187 100644 --- a/lib/hexo/post.js +++ b/lib/hexo/post.js @@ -417,7 +417,7 @@ class Post { } const options = data.markdown || {}; - if (!config.highlight.enable) options.highlight = null; + if (!config.syntax_highlighter) options.highlight = null; ctx.log.debug('Rendering post: %s', magenta(source)); // Render with markdown or other renderer diff --git a/lib/plugins/filter/before_post_render/backtick_code_block.js b/lib/plugins/filter/before_post_render/backtick_code_block.js index 871146c42e..32f3590e27 100644 --- a/lib/plugins/filter/before_post_render/backtick_code_block.js +++ b/lib/plugins/filter/before_post_render/backtick_code_block.js @@ -1,111 +1,73 @@ 'use strict'; -let highlight, prismHighlight; - const rBacktick = /^((?:[^\S\r\n]*>){0,3}[^\S\r\n]*)(`{3,}|~{3,})[^\S\r\n]*((?:.*?[^`\s])?)[^\S\r\n]*\n((?:[\s\S]*?\n)?)(?:(?:[^\S\r\n]*>){0,3}[^\S\r\n]*)\2[^\S\r\n]?(\n+|$)/gm; const rAllOptions = /([^\s]+)\s+(.+?)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/; const rLangCaption = /([^\s]+)\s*(.+)?/; const escapeSwigTag = str => str.replace(/{/g, '{').replace(/}/g, '}'); -function backtickCodeBlock(data) { - const dataContent = data.content; - - const hljsCfg = this.config.highlight || {}; - const prismCfg = this.config.prismjs || {}; +module.exports = ctx => { + return function backtickCodeBlock(data) { + const dataContent = data.content; - if ((!dataContent.includes('```') && !dataContent.includes('~~~')) || (!hljsCfg.enable && !prismCfg.enable)) return; + if ((!dataContent.includes('```') && !dataContent.includes('~~~')) || !ctx.extend.highlight.query(ctx.config.syntax_highlighter)) return; - data.content = dataContent.replace(rBacktick, ($0, start, $2, _args, _content, end) => { - let content = _content.replace(/\n$/, ''); + data.content = dataContent.replace(rBacktick, ($0, start, $2, _args, _content, end) => { + let content = _content.replace(/\n$/, ''); - // neither highlight or prismjs is enabled, return escaped content directly. - if (!hljsCfg.enable && !prismCfg.enable) return escapeSwigTag($0); + // neither highlight or prismjs is enabled, return escaped content directly. + if (!ctx.extend.highlight.query(ctx.config.syntax_highlighter)) return escapeSwigTag($0); - // Extract language and caption of code blocks - const args = _args.split('=').shift(); - let lang, caption; + // Extract language and caption of code blocks + const args = _args.split('=').shift(); + let lang, caption; - if (args) { - const match = rAllOptions.exec(args) || rLangCaption.exec(args); + if (args) { + const match = rAllOptions.exec(args) || rLangCaption.exec(args); - if (match) { - lang = match[1]; + if (match) { + lang = match[1]; - if (match[2]) { - caption = `${match[2]}`; + if (match[2]) { + caption = `${match[2]}`; - if (match[3]) { - caption += `${match[4] ? match[4] : 'link'}`; + if (match[3]) { + caption += `${match[4] ? match[4] : 'link'}`; + } } } } - } - - // PR #3765 - if (start.includes('>')) { - // heading of last line is already removed by the top RegExp "rBacktick" - const depth = start.split('>').length - 1; - const regexp = new RegExp(`^([^\\S\\r\\n]*>){0,${depth}}([^\\S\\r\\n]|$)`, 'mg'); - content = content.replace(regexp, ''); - } - // Since prismjs have better performance, so prismjs should have higher priority. - if (prismCfg.enable) { - if (!prismHighlight) prismHighlight = require('hexo-util').prismHighlight; - - const options = { - lineNumber: prismCfg.line_number, - tab: prismCfg.tab_replace, - isPreprocess: prismCfg.preprocess, - lang, - caption - }; - - content = prismHighlight(content, options); - } else if (hljsCfg.enable) { - if (!highlight) highlight = require('hexo-util').highlight; + // PR #3765 + if (start.includes('>')) { + // heading of last line is already removed by the top RegExp "rBacktick" + const depth = start.split('>').length - 1; + const regexp = new RegExp(`^([^\\S\\r\\n]*>){0,${depth}}([^\\S\\r\\n]|$)`, 'mg'); + content = content.replace(regexp, ''); + } const options = { - hljs: hljsCfg.hljs, - autoDetect: hljsCfg.auto_detect, - gutter: hljsCfg.line_number, - tab: hljsCfg.tab_replace, - wrap: hljsCfg.wrap, lang, - languageAttr: hljsCfg.language_attr, - caption + caption, + lines_length: content.split('\n').length }; + // setup line number by inline + _args = _args.replace('=+', '='); - if (options.gutter) { - hljsCfg.first_line_number = hljsCfg.first_line_number || 'always1'; - if (hljsCfg.first_line_number === 'inline') { - - // setup line number by inline - _args = _args.replace('=+', '='); - options.gutter = _args.includes('='); - - // setup firstLineNumber; - options.firstLine = options.gutter ? _args.split('=')[1] || 1 : 0; - } - } - - if (Array.isArray(hljsCfg.exclude_languages) && hljsCfg.exclude_languages.includes(options.lang)) { - // Only wrap with
- options.wrap = false; - options.gutter = false; - options.autoDetect = false; + // setup firstLineNumber; + if (_args.includes('=')) { + options.firstLineNumber = _args.split('=')[1] || 1; } - - content = highlight(content, options); - } - - return start - + '' - + escapeSwigTag(content) - + '' - + end; - }); -} - -module.exports = backtickCodeBlock; + content = ctx.extend.highlight.exec(ctx.config.syntax_highlighter, { + context: ctx, + args: [content, options] + }); + + return start + + '' + + escapeSwigTag(content) + + '' + + end; + }); + }; +}; diff --git a/lib/plugins/filter/before_post_render/index.js b/lib/plugins/filter/before_post_render/index.js index 934df0ad73..bcff7246b4 100644 --- a/lib/plugins/filter/before_post_render/index.js +++ b/lib/plugins/filter/before_post_render/index.js @@ -3,6 +3,6 @@ module.exports = ctx => { const { filter } = ctx.extend; - filter.register('before_post_render', require('./backtick_code_block')); + filter.register('before_post_render', require('./backtick_code_block')(ctx)); filter.register('before_post_render', require('./titlecase')); }; diff --git a/lib/plugins/highlight/highlight.js b/lib/plugins/highlight/highlight.js new file mode 100644 index 0000000000..c90ccd7994 --- /dev/null +++ b/lib/plugins/highlight/highlight.js @@ -0,0 +1,44 @@ +'use strict'; + +// Lazy require highlight.js +let highlight; + +module.exports = function highlightFilter(code, options) { + const hljsCfg = this.config.highlight || {}; + const line_threshold = options.line_threshold || hljsCfg.line_threshold || 0; + const shouldUseLineNumbers = typeof options.line_number === 'undefined' ? hljsCfg.line_number : options.line_number; + const surpassesLineThreshold = options.lines_length > line_threshold; + const gutter = shouldUseLineNumbers && surpassesLineThreshold; + const languageAttr = typeof options.language_attr === 'undefined' ? hljsCfg.language_attr : options.language_attr; + + const hljsOptions = { + autoDetect: hljsCfg.auto_detect, + caption: options.caption, + firstLine: options.firstLine, + gutter, + hljs: hljsCfg.hljs, + lang: options.lang, + languageAttr, + mark: options.mark, + tab: hljsCfg.tab_replace, + wrap: hljsCfg.wrap + }; + if (hljsCfg.first_line_number === 'inline') { + if (typeof options.firstLineNumber !== 'undefined') { + hljsOptions.firstLine = options.firstLineNumber; + } else { + hljsOptions.gutter = false; + } + } + + if (Array.isArray(hljsCfg.exclude_languages) && hljsCfg.exclude_languages.includes(hljsOptions.lang)) { + // Only wrap with
+ hljsOptions.wrap = false; + hljsOptions.gutter = false; + hljsOptions.autoDetect = false; + } + + if (!highlight) highlight = require('hexo-util').highlight; + + return highlight(code, hljsOptions); +}; diff --git a/lib/plugins/highlight/index.js b/lib/plugins/highlight/index.js new file mode 100644 index 0000000000..9dc22fd7d4 --- /dev/null +++ b/lib/plugins/highlight/index.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = ctx => { + const { highlight } = ctx.extend; + + highlight.register('highlight.js', require('./highlight')); + highlight.register('prismjs', require('./prism')); +}; diff --git a/lib/plugins/highlight/prism.js b/lib/plugins/highlight/prism.js new file mode 100644 index 0000000000..7d46461c96 --- /dev/null +++ b/lib/plugins/highlight/prism.js @@ -0,0 +1,26 @@ +'use strict'; + +// Lazy require prismjs +let prismHighlight; + +module.exports = function(code, options) { + const prismjsCfg = this.config.prismjs || {}; + const line_threshold = options.line_threshold || prismjsCfg.line_threshold || 0; + const shouldUseLineNumbers = typeof options.line_number === 'undefined' ? prismjsCfg.line_number : options.line_number; + const surpassesLineThreshold = options.lines_length > line_threshold; + const lineNumber = shouldUseLineNumbers && surpassesLineThreshold; + + const prismjsOptions = { + caption: options.caption, + firstLine: options.firstLine, + isPreprocess: prismjsCfg.preprocess, + lang: options.lang, + lineNumber, + mark: options.mark, + tab: prismjsCfg.tab_replace + }; + + if (!prismHighlight) prismHighlight = require('hexo-util').prismHighlight; + + return prismHighlight(code, prismjsOptions); +}; diff --git a/lib/plugins/tag/code.js b/lib/plugins/tag/code.js index ecb7ccce23..d4620dcccc 100644 --- a/lib/plugins/tag/code.js +++ b/lib/plugins/tag/code.js @@ -4,9 +4,6 @@ const { escapeHTML } = require('hexo-util'); -// Lazy require highlight.js & prismjs -let highlight, prismHighlight; - const rCaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/\S+)\s+(.+)/i; const rCaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/\S+)/i; const rCaption = /\S[\S\s]*/; @@ -120,11 +117,9 @@ function parseArgs(args) { } module.exports = ctx => function codeTag(args, content) { - const hljsCfg = ctx.config.highlight || {}; - const prismjsCfg = ctx.config.prismjs || {}; // If neither highlight.js nor prism.js is enabled, return escaped code directly - if (!hljsCfg.enable && !prismjsCfg.enable) { + if (!ctx.extend.highlight.query(ctx.config.syntax_highlighter)) { return `
${escapeHTML(content)}
`; } @@ -143,68 +138,12 @@ module.exports = ctx => function codeTag(args, content) { return `
${escapeHTML(content)}
`; } - const { lang, language_attr, firstLine, caption, line_number, line_threshold, mark, wrap } = parseArgs(args); - - if (prismjsCfg.enable) { - const shouldUseLineNumbers = typeof line_number !== 'undefined' ? line_number : prismjsCfg.line_number; - let surpassesLineThreshold; - - if (typeof line_threshold !== 'undefined') { - surpassesLineThreshold = content.split('\n').length > line_threshold; - } else { - surpassesLineThreshold = content.split('\n').length > (prismjsCfg.line_threshold || 0); - } - - const prismjsOption = { - lang, - firstLine, - caption, - lineNumber: shouldUseLineNumbers && surpassesLineThreshold, - mark, - tab: prismjsCfg.tab_replace, - isPreprocess: prismjsCfg.preprocess - }; - - if (!prismHighlight) prismHighlight = require('hexo-util').prismHighlight; - - content = prismHighlight(content, prismjsOption); - } else { - const shouldUseLineNumbers = typeof line_number !== 'undefined' - ? line_number : hljsCfg.line_number; - let surpassesLineThreshold; - - if (typeof line_threshold !== 'undefined') { - surpassesLineThreshold - = content.split('\n').length > line_threshold; - } else { - surpassesLineThreshold - = content.split('\n').length > (hljsCfg.line_threshold || 0); - } - - const hljsOption = { - lang: typeof lang !== 'undefined' ? lang : '', - firstLine, - caption, - gutter: shouldUseLineNumbers && surpassesLineThreshold, - hljs: hljsCfg.hljs, - mark, - tab: hljsCfg.tab_replace, - autoDetect: hljsCfg.auto_detect, - wrap: typeof wrap === 'boolean' ? wrap : hljsCfg.wrap, - languageAttr: typeof language_attr === 'boolean' ? language_attr : hljsCfg.language_attr - }; - - if (Array.isArray(hljsCfg.exclude_languages) && hljsCfg.exclude_languages.includes(hljsOption.lang)) { - // Only wrap with
- hljsOption.wrap = false; - hljsOption.gutter = false; - hljsOption.autoDetect = false; - } - - if (!highlight) highlight = require('hexo-util').highlight; - - content = highlight(content, hljsOption); - } + const options = parseArgs(args); + options.lines_length = content.split('\n').length; + content = ctx.extend.highlight.exec(ctx.config.syntax_highlighter, { + context: ctx, + args: [content, options] + }); return content.replace(/{/g, '{').replace(/}/g, '}'); }; diff --git a/lib/plugins/tag/include_code.js b/lib/plugins/tag/include_code.js index a024d81ac2..8d9d1a9a95 100644 --- a/lib/plugins/tag/include_code.js +++ b/lib/plugins/tag/include_code.js @@ -3,9 +3,6 @@ const { exists, readFile } = require('hexo-fs'); const { basename, extname, join, posix } = require('path'); -// Lazy require highlight.js & prismjs -let highlight, prismHighlight; - const rCaptionTitleFile = /(.*)?(?:\s+|^)(\/*\S+)/; const rLang = /\s*lang:(\w+)/i; const rFrom = /\s*from:(\d+)/i; @@ -57,9 +54,6 @@ module.exports = ctx => function includeCodeTag(args) { const title = match[1] || basename(path); const caption = `${title}view raw`; - const hljsCfg = ctx.config.highlight || {}; - const prismjsCfg = ctx.config.prismjs || {}; - return exists(src).then(exist => { if (exist) return readFile(src); }).then(code => { @@ -68,37 +62,16 @@ module.exports = ctx => function includeCodeTag(args) { const lines = code.split('\n'); code = lines.slice(from, to).join('\n').trim(); - if (prismjsCfg.enable) { - const line_threshold = prismjsCfg.line_threshold - ? prismjsCfg.line_threshold : 0; - - const prismjsOptions = { + if (ctx.extend.highlight.query(ctx.config.syntax_highlighter)) { + const options = { lang, caption, - lineNumber: prismjsCfg.line_number && lines.length > line_threshold, - tab: prismjsCfg.tab_replace, - isPreprocess: prismjsCfg.preprocess + lines_length: lines.length }; - - if (!prismHighlight) prismHighlight = require('hexo-util').prismHighlight; - - return prismHighlight(code, prismjsOptions); - } else if (hljsCfg.enable) { - const line_threshold = hljsCfg.line_threshold - ? hljsCfg.line_threshold : 0; - - const hljsOptions = { - lang, - languageAttr: hljsCfg.language_attr, - caption, - gutter: hljsCfg.line_number && lines.length > line_threshold, - hljs: hljsCfg.hljs, - tab: hljsCfg.tab_replace - }; - - if (!highlight) highlight = require('hexo-util').highlight; - - return highlight(code, hljsOptions); + return ctx.extend.highlight.exec(ctx.config.syntax_highlighter, { + context: ctx, + args: [code, options] + }); } return `
${code}
`; diff --git a/test/scripts/filters/backtick_code_block.js b/test/scripts/filters/backtick_code_block.js index 990084b19c..4b0d75e31b 100644 --- a/test/scripts/filters/backtick_code_block.js +++ b/test/scripts/filters/backtick_code_block.js @@ -6,7 +6,8 @@ const defaultConfig = require('../../../lib/hexo/default_config'); describe('Backtick code block', () => { const Hexo = require('../../../lib/hexo'); const hexo = new Hexo(); - const codeBlock = require('../../../lib/plugins/filter/before_post_render/backtick_code_block').bind(hexo); + require('../../../lib/plugins/highlight/')(hexo); + const codeBlock = require('../../../lib/plugins/filter/before_post_render/backtick_code_block')(hexo); const code = [ 'if (tired && night) {', @@ -47,8 +48,7 @@ describe('Backtick code block', () => { const data = {content}; - hexo.config.highlight.enable = false; - hexo.config.prismjs.enable = false; + hexo.config.syntax_highlighter = ''; codeBlock(data); data.content.should.eql(content); }); @@ -75,6 +75,10 @@ describe('Backtick code block', () => { }); describe('highlightjs', () => { + beforeEach(() => { + hexo.config.syntax_highlighter = 'highlight.js'; + }); + it('shorthand', () => { const data = { content: 'Hello, world!' @@ -503,8 +507,7 @@ describe('Backtick code block', () => { describe('prismjs', () => { beforeEach(() => { - hexo.config.highlight.enable = false; - hexo.config.prismjs.enable = true; + hexo.config.syntax_highlighter = 'prismjs'; }); it('default', () => { diff --git a/test/scripts/hexo/load_config.js b/test/scripts/hexo/load_config.js index 1d6d20f6c0..ce9698d068 100644 --- a/test/scripts/hexo/load_config.js +++ b/test/scripts/hexo/load_config.js @@ -205,7 +205,7 @@ describe('Load config', () => { try { await writeFile(hexo.config_path, content); await loadConfig(hexo); - hexo.config.highlight.enable.should.be.true; + hexo.config.highlight.line_number.should.be.true; hexo.config.highlight.tab_replace.should.eql('yoooo'); } finally { await unlink(hexo.config_path); diff --git a/test/scripts/hexo/post.js b/test/scripts/hexo/post.js index e2ab65205c..23f39c9b1a 100644 --- a/test/scripts/hexo/post.js +++ b/test/scripts/hexo/post.js @@ -12,6 +12,7 @@ const escapeSwigTag = str => str.replace(/{/g, '{').replace(/}/g, '}') describe('Post', () => { const Hexo = require('../../../lib/hexo'); const hexo = new Hexo(join(__dirname, 'post_test')); + require('../../../lib/plugins/highlight/')(hexo); const { post } = hexo; const now = Date.now(); let clock; @@ -913,8 +914,7 @@ describe('Post', () => { }); it('render() - shouln\'t break curly brackets', async () => { - hexo.config.prismjs.enable = true; - hexo.config.highlight.enable = false; + hexo.config.syntax_highlighter = 'prismjs'; const content = [ '\\begin{equation}', @@ -930,8 +930,7 @@ describe('Post', () => { data.content.should.include('\\begin{equation}'); data.content.should.include('\\end{equation}'); - hexo.config.prismjs.enable = false; - hexo.config.highlight.enable = true; + hexo.config.syntax_highlighter = 'highlight.js'; }); // #2321 @@ -1330,8 +1329,7 @@ describe('Post', () => { }); it('render() - issue #4460', async () => { - hexo.config.prismjs.enable = true; - hexo.config.highlight.enable = false; + hexo.config.syntax_highlighter = 'prismjs'; const content = fixture.content_for_issue_4460; @@ -1342,13 +1340,11 @@ describe('Post', () => { data.content.should.not.include('hexoPostRenderEscape'); - hexo.config.prismjs.enable = false; - hexo.config.highlight.enable = true; + hexo.config.syntax_highlighter = 'highlight.js'; }); it('render() - empty tag name', async () => { - hexo.config.prismjs.enable = true; - hexo.config.highlight.enable = false; + hexo.config.syntax_highlighter = 'prismjs'; const content = 'Disable rendering of Nunjucks tag `{{ }}` / `{% %}`'; @@ -1360,7 +1356,6 @@ describe('Post', () => { data.content.should.include(escapeSwigTag('{{ }}')); data.content.should.include(escapeSwigTag('{% %}')); - hexo.config.prismjs.enable = false; - hexo.config.highlight.enable = true; + hexo.config.syntax_highlighter = 'highlight.js'; }); }); diff --git a/test/scripts/tags/code.js b/test/scripts/tags/code.js index 4a1220f9c1..406fe69c24 100644 --- a/test/scripts/tags/code.js +++ b/test/scripts/tags/code.js @@ -6,6 +6,7 @@ const cheerio = require('cheerio'); describe('code', () => { const Hexo = require('../../../lib/hexo'); const hexo = new Hexo(); + require('../../../lib/plugins/highlight/')(hexo); const codeTag = require('../../../lib/plugins/tag/code')(hexo); const { escapeHTML } = util; @@ -114,12 +115,12 @@ describe('code', () => { }); it('disabled', () => { - hexo.config.highlight.enable = false; + hexo.config.syntax_highlighter = ''; const result = code('', fixture); result.should.eql('
' + escapeHTML(fixture) + '
'); - hexo.config.highlight.enable = true; + hexo.config.syntax_highlighter = 'highlight.js'; }); it('first_line', () => { @@ -185,8 +186,7 @@ describe('code', () => { describe('prismjs', () => { beforeEach(() => { - hexo.config.highlight.enable = false; - hexo.config.prismjs.enable = true; + hexo.config.syntax_highlighter = 'prismjs'; }); it('default', () => { @@ -246,13 +246,12 @@ describe('code', () => { }); it('disabled', () => { - hexo.config.highlight.enable = false; - hexo.config.prismjs.enable = false; + hexo.config.syntax_highlighter = ''; const result = code('', fixture); result.should.eql('
' + escapeHTML(fixture) + '
'); - hexo.config.highlight.enable = true; + hexo.config.syntax_highlighter = 'highlight.js'; }); it('first_line', () => { diff --git a/test/scripts/tags/include_code.js b/test/scripts/tags/include_code.js index 48af4a33c2..ca8b4c7884 100644 --- a/test/scripts/tags/include_code.js +++ b/test/scripts/tags/include_code.js @@ -8,6 +8,7 @@ const Promise = require('bluebird'); describe('include_code', () => { const Hexo = require('../../../lib/hexo'); const hexo = new Hexo(join(__dirname, 'include_code_test')); + require('../../../lib/plugins/highlight/')(hexo); const includeCode = Promise.method(require('../../../lib/plugins/tag/include_code')(hexo)); const path = join(hexo.source_dir, hexo.config.code_dir, 'test.js'); const defaultCfg = JSON.parse(JSON.stringify(hexo.config)); @@ -30,8 +31,7 @@ describe('include_code', () => { describe('highlightjs', () => { it('default', async () => { - hexo.config.highlight.enable = true; - hexo.config.prismjs.enable = false; + hexo.config.syntax_highlighter = 'highlight.js'; const expected = highlight(fixture, { lang: 'js', @@ -124,7 +124,7 @@ describe('include_code', () => { }); it('disabled', async () => { - hexo.config.highlight.enable = false; + hexo.config.syntax_highlighter = ''; const result = await code('test.js'); result.should.eql('
' + fixture + '
'); @@ -133,8 +133,7 @@ describe('include_code', () => { describe('prismjs', () => { beforeEach(() => { - hexo.config.highlight.enable = false; - hexo.config.prismjs.enable = true; + hexo.config.syntax_highlighter = 'prismjs'; }); it('default', async () => { @@ -213,8 +212,7 @@ describe('include_code', () => { }); it('disabled', async () => { - hexo.config.highlight.enable = false; - hexo.config.prismjs.enable = false; + hexo.config.syntax_highlighter = ''; const result = await code('test.js'); result.should.eql('
' + fixture + '
'); From 4f2dde488cf6caec871c0b25681d11f5cc61ae22 Mon Sep 17 00:00:00 2001 From: yoshinorin Date: Sat, 31 Dec 2022 17:44:28 +0900 Subject: [PATCH 06/29] refactor: use the `WHATWG URL API` instead of `url.resolve` (#5136) --- lib/plugins/tag/asset_img.js | 3 +-- lib/plugins/tag/asset_link.js | 3 +-- lib/plugins/tag/asset_path.js | 3 +-- lib/plugins/tag/post_link.js | 3 +-- lib/plugins/tag/post_path.js | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/plugins/tag/asset_img.js b/lib/plugins/tag/asset_img.js index df1b67bd34..5189c28a27 100644 --- a/lib/plugins/tag/asset_img.js +++ b/lib/plugins/tag/asset_img.js @@ -1,6 +1,5 @@ 'use strict'; -const { resolve } = require('url'); const img = require('./img'); const { encodeURL } = require('hexo-util'); @@ -20,7 +19,7 @@ module.exports = ctx => { for (let i = 0; i < len; i++) { const asset = PostAsset.findOne({post: this._id, slug: args[i]}); if (asset) { - args[i] = encodeURL(resolve('/', asset.path)); + args[i] = encodeURL(new URL(asset.path, ctx.config.url).pathname); return img(ctx)(args); } } diff --git a/lib/plugins/tag/asset_link.js b/lib/plugins/tag/asset_link.js index c51dc3e005..8f3225e297 100644 --- a/lib/plugins/tag/asset_link.js +++ b/lib/plugins/tag/asset_link.js @@ -1,7 +1,6 @@ 'use strict'; const { encodeURL, escapeHTML } = require('hexo-util'); -const { resolve } = require('url'); /** * Asset link tag @@ -30,7 +29,7 @@ module.exports = ctx => { const attrTitle = escapeHTML(title); if (escape === 'true') title = attrTitle; - const link = encodeURL(resolve(ctx.config.root, asset.path)); + const link = encodeURL(new URL(asset.path, ctx.config.url).pathname); return `${title}`; }; diff --git a/lib/plugins/tag/asset_path.js b/lib/plugins/tag/asset_path.js index 88be887673..d988176d30 100644 --- a/lib/plugins/tag/asset_path.js +++ b/lib/plugins/tag/asset_path.js @@ -1,6 +1,5 @@ 'use strict'; -const { resolve } = require('url'); const { encodeURL } = require('hexo-util'); /** @@ -19,7 +18,7 @@ module.exports = ctx => { const asset = PostAsset.findOne({post: this._id, slug}); if (!asset) return; - const path = encodeURL(resolve(ctx.config.root, asset.path)); + const path = encodeURL(new URL(asset.path, ctx.config.url).pathname); return path; }; diff --git a/lib/plugins/tag/post_link.js b/lib/plugins/tag/post_link.js index 553e7599ce..838b046560 100644 --- a/lib/plugins/tag/post_link.js +++ b/lib/plugins/tag/post_link.js @@ -1,7 +1,6 @@ 'use strict'; const { encodeURL, escapeHTML } = require('hexo-util'); -const { resolve } = require('url'); const { postFindOneFactory } = require('./'); /** @@ -35,7 +34,7 @@ module.exports = ctx => { const attrTitle = escapeHTML(post.title); if (escape === 'true') title = escapeHTML(title); - const link = encodeURL(resolve(ctx.config.root, post.path)); + const link = encodeURL(new URL(post.path, ctx.config.url).pathname); return `${title}`; }; diff --git a/lib/plugins/tag/post_path.js b/lib/plugins/tag/post_path.js index 89346560f4..679f65039f 100644 --- a/lib/plugins/tag/post_path.js +++ b/lib/plugins/tag/post_path.js @@ -1,6 +1,5 @@ 'use strict'; -const { resolve } = require('url'); const { encodeURL } = require('hexo-util'); const { postFindOneFactory } = require('./'); @@ -19,7 +18,7 @@ module.exports = ctx => { const post = factory({ slug }) || factory({ title: slug }); if (!post) return; - const link = encodeURL(resolve(ctx.config.root, post.path)); + const link = encodeURL(new URL(post.path, ctx.config.url).pathname); return link; }; From d5f3f82fab2c1ef85525e142b978a904632ef425 Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Mon, 6 Feb 2023 22:22:48 +0800 Subject: [PATCH 07/29] fix: Failed to create post with special character title (#5149) --- lib/hexo/post.js | 4 +- test/scripts/console/new.js | 84 +++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/lib/hexo/post.js b/lib/hexo/post.js index 2b91d56187..2df362d2fa 100644 --- a/lib/hexo/post.js +++ b/lib/hexo/post.js @@ -191,7 +191,9 @@ const prepareFrontMatter = (data, jsonMode) => { } else if (moment.isDate(item)) { data[key] = moment.utc(item).format('YYYY-MM-DD HH:mm:ss'); } else if (typeof item === 'string') { - if (jsonMode || item.includes(':') || item.startsWith('#') || item.startsWith('!!')) data[key] = `"${item}"`; + if (jsonMode || item.includes(':') || item.startsWith('#') || item.startsWith('!!') + || item.includes('{') || item.includes('}') || item.includes('[') || item.includes(']') + || item.includes('\'') || item.includes('"')) data[key] = `"${item.replace(/"/g, '\\"')}"`; } } diff --git a/test/scripts/console/new.js b/test/scripts/console/new.js index e578a2d047..8e64429ae0 100644 --- a/test/scripts/console/new.js +++ b/test/scripts/console/new.js @@ -247,4 +247,88 @@ describe('new', () => { await unlink(path); }); + + it('special character - 1', async () => { + const date = moment(now); + const path = join(hexo.source_dir, '_posts', 'Hello-World.md'); + const body = [ + 'title: \'[Hello] World\'', + 'foo: bar', + 'date: ' + date.format('YYYY-MM-DD HH:mm:ss'), + 'tags:', + '---' + ].join('\n') + '\n'; + + await n({ + _: ['[Hello] World'], + foo: 'bar' + }); + const content = await readFile(path); + content.should.eql(body); + + await unlink(path); + }); + + it('special character - 2', async () => { + const date = moment(now); + const path = join(hexo.source_dir, '_posts', 'Hello-World.md'); + const body = [ + 'title: \'{Hello} World\'', + 'foo: bar', + 'date: ' + date.format('YYYY-MM-DD HH:mm:ss'), + 'tags:', + '---' + ].join('\n') + '\n'; + + await n({ + _: ['{Hello} World'], + foo: 'bar' + }); + const content = await readFile(path); + content.should.eql(body); + + await unlink(path); + }); + + it('special character - 3', async () => { + const date = moment(now); + const path = join(hexo.source_dir, '_posts', 'Hello-World.md'); + const body = [ + 'title: \'\'\'Hello\'\' World\'', + 'foo: bar', + 'date: ' + date.format('YYYY-MM-DD HH:mm:ss'), + 'tags:', + '---' + ].join('\n') + '\n'; + + await n({ + _: ['\'Hello\' World'], + foo: 'bar' + }); + const content = await readFile(path); + content.should.eql(body); + + await unlink(path); + }); + + it('special character - 4', async () => { + const date = moment(now); + const path = join(hexo.source_dir, '_posts', 'Hello-World.md'); + const body = [ + 'title: \'"Hello" World\'', + 'foo: bar', + 'date: ' + date.format('YYYY-MM-DD HH:mm:ss'), + 'tags:', + '---' + ].join('\n') + '\n'; + + await n({ + _: ['"Hello" World'], + foo: 'bar' + }); + const content = await readFile(path); + content.should.eql(body); + + await unlink(path); + }); }); From cb19b2938d1f7882a4cb41a98974a3d673a63b45 Mon Sep 17 00:00:00 2001 From: Baoshuo Ren Date: Tue, 28 Feb 2023 00:54:43 +0800 Subject: [PATCH 08/29] feat: add an option to disable titlecase in post (#5156) --- .../filter/before_post_render/titlecase.js | 2 +- test/scripts/filters/titlecase.js | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/plugins/filter/before_post_render/titlecase.js b/lib/plugins/filter/before_post_render/titlecase.js index 8c22295da6..0fad5bc4e9 100644 --- a/lib/plugins/filter/before_post_render/titlecase.js +++ b/lib/plugins/filter/before_post_render/titlecase.js @@ -3,7 +3,7 @@ let titlecase; function titlecaseFilter(data) { - if (!this.config.titlecase || !data.title) return; + if (!(typeof data.titlecase !== 'undefined' ? data.titlecase : this.config.titlecase) || !data.title) return; if (!titlecase) titlecase = require('titlecase'); data.title = titlecase(data.title); diff --git a/test/scripts/filters/titlecase.js b/test/scripts/filters/titlecase.js index 38e3ae43f0..126b2a156e 100644 --- a/test/scripts/filters/titlecase.js +++ b/test/scripts/filters/titlecase.js @@ -22,4 +22,23 @@ describe('Titlecase', () => { titlecase(data); data.title.should.eql('Today Is a Good Day'); }); + + it('enabled globally but disabled in a specify post', () => { + const title = 'Today is a good day'; + const data = {title, titlecase: false}; + hexo.config.titlecase = true; + + titlecase(data); + data.title.should.eql('Today is a good day'); + }); + + it('disabled globally but enabled in a specify post', () => { + const title = 'Today is a good day'; + const data = {title, titlecase: true}; + hexo.config.titlecase = false; + + titlecase(data); + data.title.should.eql('Today Is a Good Day'); + }); + }); From 7edbf25d5b4c4d7fdf99ff2439cfd9b2cb1cfe0d Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Fri, 10 Mar 2023 16:58:37 +0800 Subject: [PATCH 09/29] fix(box): check for invalid file (#5173) --- lib/box/index.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/box/index.js b/lib/box/index.js index ebea4c3864..2975570b8c 100644 --- a/lib/box/index.js +++ b/lib/box/index.js @@ -78,8 +78,9 @@ class Box extends EventEmitter { } _readDir(base, prefix = '') { + const { context: ctx } = this; const results = []; - return readDirWalker(base, results, this.ignore, prefix) + return readDirWalker(ctx, base, results, this.ignore, prefix) .return(results) .map(path => this._checkFileStatus(path)) .map(file => this._processFile(file.type, file.path).return(file.path)); @@ -155,7 +156,7 @@ class Box extends EventEmitter { path }); }).catch(err => { - ctx.log.error({err}, 'Process failed: %s', magenta(path)); + ctx.log.error({ err }, 'Process failed: %s', magenta(path)); }).finally(() => { this._processingFiles[path] = false; }).thenReturn(path); @@ -245,21 +246,28 @@ function isIgnoreMatch(path, ignore) { return path && ignore && ignore.length && isMatch(path, ignore); } -function readDirWalker(base, results, ignore, prefix) { +function readDirWalker(ctx, base, results, ignore, prefix) { if (isIgnoreMatch(base, ignore)) return Promise.resolve(); return Promise.map(readdir(base).catch(err => { + ctx.log.error({ err }, 'Failed to read directory: %s', base); if (err && err.code === 'ENOENT') return []; throw err; }), async path => { const fullpath = join(base, path); - const stats = await stat(fullpath); + const stats = await stat(fullpath).catch(err => { + ctx.log.error({ err }, 'Failed to stat file: %s', fullpath); + if (err && err.code === 'ENOENT') return null; + throw err; + }); const prefixdPath = `${prefix}${path}`; - if (stats.isDirectory()) { - return readDirWalker(fullpath, results, ignore, `${prefixdPath}/`); - } - if (!isIgnoreMatch(fullpath, ignore)) { - results.push(prefixdPath); + if (stats) { + if (stats.isDirectory()) { + return readDirWalker(ctx, fullpath, results, ignore, `${prefixdPath}/`); + } + if (!isIgnoreMatch(fullpath, ignore)) { + results.push(prefixdPath); + } } }); } From 148ed7c91c96d9ef151020d339ccc242f16951ea Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Wed, 15 Mar 2023 19:39:51 +0800 Subject: [PATCH 10/29] refactor: migrate typescript (#5092) * refactor: esm * refactor: migrate typescript * update files * remove `use strict` * fix indentation * refactor: migrate typescript * refactor: migrate typescript * update * export from * extend/filter * post * Schema and SchemaType * NunjucksError * declare module * update tests * fix export * update * update * number_format * update highlight * update * add secondary argument when create `Permalink` instance * specify `eslint` target directory * ignore two rules for testing * use `@ts-expect-error` for avoiding compile error * use `any` for avoiding compile error * chore: add `dist/` to `.gitignore` * test(eslint): update `.eslintrc` * refactor: `var` to `const` * refactor: delete unnecessary `'use strict';` * test: use `dist/modules/types/moment/SchemaTypeMoment` instead of `warehouse.SchemaTypeMoment` * fix: export of processors * test: fix bind * test: fix processer * fix fs import * fix hexo-i18n and hexo-log * fix param order * build hexo in benchmark * fix eslint * fix export & drop travis * Update .husky/pre-commit * add spaces * refactor: ts debounce fn * fix: lint errors * fix: lint errors --------- Co-authored-by: yoshinorin Co-authored-by: Baoshuo --- .eslintrc.json | 17 +- .gitignore | 1 + lib/box/{file.js => file.ts} | 15 +- lib/box/{index.js => index.ts} | 60 ++++--- lib/extend/{console.js => console.ts} | 11 +- lib/extend/{deployer.js => deployer.ts} | 12 +- lib/extend/{filter.js => filter.ts} | 43 +++-- lib/extend/{generator.js => generator.ts} | 11 +- lib/extend/{helper.js => helper.ts} | 10 +- lib/extend/index.js | 17 -- lib/extend/index.ts | 11 ++ lib/extend/{injector.js => injector.ts} | 10 +- lib/extend/{migrator.js => migrator.ts} | 12 +- lib/extend/{processor.js => processor.ts} | 10 +- lib/extend/{renderer.js => renderer.ts} | 13 +- ...yntax_highlight.js => syntax_highlight.ts} | 24 ++- lib/extend/{tag.js => tag.ts} | 34 ++-- .../{default_config.js => default_config.ts} | 4 +- lib/hexo/{index.js => index.ts} | 168 +++++++++++++----- lib/hexo/{load_config.js => load_config.ts} | 22 ++- .../{load_database.js => load_database.ts} | 12 +- lib/hexo/{load_plugins.js => load_plugins.ts} | 14 +- ...d_theme_config.js => load_theme_config.ts} | 14 +- lib/hexo/{locals.js => locals.ts} | 9 +- ...ti_config_path.js => multi_config_path.ts} | 20 +-- lib/hexo/{post.js => post.ts} | 53 ++++-- ...{register_models.js => register_models.ts} | 6 +- lib/hexo/{render.js => render.ts} | 15 +- lib/hexo/{router.js => router.ts} | 42 +++-- lib/hexo/{scaffold.js => scaffold.ts} | 12 +- lib/hexo/{source.js => source.ts} | 6 +- .../{update_package.js => update_package.ts} | 16 +- ...{validate_config.js => validate_config.ts} | 4 +- lib/models/{asset.js => asset.ts} | 10 +- lib/models/{cache.js => cache.ts} | 10 +- lib/models/{category.js => category.ts} | 12 +- lib/models/data.js | 12 -- lib/models/data.ts | 10 ++ lib/models/index.js | 16 -- lib/models/index.ts | 10 ++ lib/models/{page.js => page.ts} | 16 +- lib/models/{post.js => post.ts} | 24 ++- lib/models/{post_asset.js => post_asset.ts} | 12 +- lib/models/post_category.js | 12 -- lib/models/post_category.ts | 10 ++ lib/models/post_tag.js | 12 -- lib/models/post_tag.ts | 10 ++ lib/models/{tag.js => tag.ts} | 10 +- lib/models/types/{moment.js => moment.ts} | 19 +- lib/plugins/console/{clean.js => clean.ts} | 16 +- lib/plugins/console/{config.js => config.ts} | 16 +- lib/plugins/console/{deploy.js => deploy.ts} | 11 +- .../console/{generate.js => generate.ts} | 34 ++-- lib/plugins/console/{index.js => index.ts} | 6 +- .../console/list/{category.js => category.ts} | 10 +- .../console/list/{common.js => common.ts} | 8 +- .../console/list/{index.js => index.ts} | 16 +- lib/plugins/console/list/{page.js => page.ts} | 10 +- lib/plugins/console/list/{post.js => post.ts} | 10 +- .../console/list/{route.js => route.ts} | 6 +- lib/plugins/console/list/{tag.js => tag.ts} | 10 +- .../console/{migrate.js => migrate.ts} | 6 +- lib/plugins/console/{new.js => new.ts} | 10 +- .../console/{publish.js => publish.ts} | 8 +- lib/plugins/console/{render.js => render.ts} | 16 +- .../{excerpt.js => excerpt.ts} | 4 +- .../{external_link.js => external_link.ts} | 6 +- .../after_post_render/{index.js => index.ts} | 4 +- .../{external_link.js => external_link.ts} | 6 +- .../after_render/{index.js => index.ts} | 4 +- .../{meta_generator.js => meta_generator.ts} | 4 +- .../filter/before_exit/{index.js => index.ts} | 4 +- .../{save_database.js => save_database.ts} | 4 +- .../before_generate/{index.js => index.ts} | 4 +- .../{render_post.js => render_post.ts} | 8 +- ...k_code_block.js => backtick_code_block.ts} | 13 +- .../before_post_render/{index.js => index.ts} | 4 +- .../{titlecase.js => titlecase.ts} | 4 +- lib/plugins/filter/{index.js => index.ts} | 4 +- .../{new_post_path.js => new_post_path.ts} | 27 +-- .../{post_permalink.js => post_permalink.ts} | 15 +- .../template_locals/{i18n.js => i18n.ts} | 6 +- .../template_locals/{index.js => index.ts} | 4 +- lib/plugins/generator/{asset.js => asset.ts} | 33 ++-- lib/plugins/generator/{index.js => index.ts} | 4 +- lib/plugins/generator/{page.js => page.ts} | 4 +- lib/plugins/generator/{post.js => post.ts} | 4 +- lib/plugins/helper/{css.js => css.ts} | 8 +- lib/plugins/helper/{date.js => date.ts} | 26 ++- lib/plugins/helper/{debug.js => debug.ts} | 8 +- .../helper/{favicon_tag.js => favicon_tag.ts} | 6 +- .../helper/{feed_tag.js => feed_tag.ts} | 15 +- lib/plugins/helper/format.js | 19 -- lib/plugins/helper/format.ts | 15 ++ .../{fragment_cache.js => fragment_cache.ts} | 6 +- lib/plugins/helper/full_url_for.js | 6 - lib/plugins/helper/full_url_for.ts | 6 + lib/plugins/helper/gravatar.js | 5 - lib/plugins/helper/gravatar.ts | 2 + lib/plugins/helper/image_tag.js | 17 -- lib/plugins/helper/image_tag.ts | 26 +++ lib/plugins/helper/{index.js => index.ts} | 4 +- lib/plugins/helper/{is.js => is.ts} | 22 ++- lib/plugins/helper/{js.js => js.ts} | 8 +- lib/plugins/helper/link_to.js | 28 --- lib/plugins/helper/link_to.ts | 45 +++++ .../{list_archives.js => list_archives.ts} | 28 ++- ...{list_categories.js => list_categories.ts} | 12 +- .../helper/{list_posts.js => list_posts.ts} | 6 +- .../helper/{list_tags.js => list_tags.ts} | 10 +- lib/plugins/helper/{mail_to.js => mail_to.ts} | 23 ++- .../helper/{markdown.js => markdown.ts} | 4 +- .../{meta_generator.js => meta_generator.ts} | 4 +- .../{number_format.js => number_format.ts} | 14 +- .../helper/{open_graph.js => open_graph.ts} | 38 ++-- .../helper/{paginator.js => paginator.ts} | 29 ++- lib/plugins/helper/{partial.js => partial.ts} | 9 +- lib/plugins/helper/relative_url.js | 7 - lib/plugins/helper/relative_url.ts | 5 + lib/plugins/helper/render.js | 8 - lib/plugins/helper/render.ts | 6 + .../helper/{search_form.js => search_form.ts} | 12 +- .../helper/{tagcloud.js => tagcloud.ts} | 10 +- lib/plugins/helper/{toc.js => toc.ts} | 21 ++- lib/plugins/helper/url_for.js | 7 - lib/plugins/helper/url_for.ts | 5 + .../highlight/{highlight.js => highlight.ts} | 2 - lib/plugins/highlight/{index.js => index.ts} | 2 - lib/plugins/highlight/{prism.js => prism.ts} | 2 - lib/plugins/injector/{index.js => index.ts} | 4 +- lib/plugins/processor/{asset.js => asset.ts} | 18 +- .../processor/{common.js => common.ts} | 26 ++- lib/plugins/processor/{data.js => data.ts} | 8 +- lib/plugins/processor/{index.js => index.ts} | 4 +- lib/plugins/processor/{post.js => post.ts} | 18 +- lib/plugins/renderer/{index.js => index.ts} | 4 +- lib/plugins/renderer/{json.js => json.ts} | 4 +- .../renderer/{nunjucks.js => nunjucks.ts} | 10 +- lib/plugins/renderer/{plain.js => plain.ts} | 4 +- lib/plugins/renderer/{yaml.js => yaml.ts} | 12 +- .../tag/{asset_img.js => asset_img.ts} | 8 +- .../tag/{asset_link.js => asset_link.ts} | 6 +- .../tag/{asset_path.js => asset_path.ts} | 6 +- .../tag/{blockquote.js => blockquote.ts} | 6 +- lib/plugins/tag/{code.js => code.ts} | 20 ++- lib/plugins/tag/{iframe.js => iframe.ts} | 6 +- lib/plugins/tag/{img.js => img.ts} | 6 +- .../tag/{include_code.js => include_code.ts} | 10 +- lib/plugins/tag/{index.js => index.ts} | 10 +- lib/plugins/tag/{link.js => link.ts} | 6 +- .../tag/{post_link.js => post_link.ts} | 8 +- .../tag/{post_path.js => post_path.ts} | 8 +- .../tag/{pullquote.js => pullquote.ts} | 4 +- lib/theme/{index.js => index.ts} | 33 ++-- lib/theme/processors/{config.js => config.ts} | 15 +- lib/theme/processors/{i18n.js => i18n.ts} | 17 +- lib/theme/processors/{source.js => source.ts} | 17 +- lib/theme/processors/{view.js => view.ts} | 15 +- lib/theme/{view.js => view.ts} | 33 +++- package.json | 26 +-- test/.eslintrc | 6 + test/benchmark.js | 9 +- test/scripts/box/box.js | 4 +- test/scripts/box/file.js | 4 +- test/scripts/console/clean.js | 4 +- test/scripts/console/config.js | 4 +- test/scripts/console/deploy.js | 6 +- test/scripts/console/generate.js | 8 +- test/scripts/console/list.js | 6 +- test/scripts/console/list_categories.js | 4 +- test/scripts/console/list_page.js | 4 +- test/scripts/console/list_post.js | 4 +- test/scripts/console/list_route.js | 4 +- test/scripts/console/list_tags.js | 4 +- test/scripts/console/migrate.js | 6 +- test/scripts/console/new.js | 4 +- test/scripts/console/publish.js | 6 +- test/scripts/console/render.js | 6 +- test/scripts/extend/console.js | 2 +- test/scripts/extend/deployer.js | 2 +- test/scripts/extend/filter.js | 2 +- test/scripts/extend/generator.js | 2 +- test/scripts/extend/helper.js | 2 +- test/scripts/extend/injector.js | 2 +- test/scripts/extend/migrator.js | 2 +- test/scripts/extend/processor.js | 2 +- test/scripts/extend/renderer.js | 2 +- test/scripts/extend/tag.js | 2 +- test/scripts/extend/tag_errors.js | 2 +- test/scripts/filters/backtick_code_block.js | 8 +- test/scripts/filters/excerpt.js | 4 +- test/scripts/filters/external_link.js | 12 +- test/scripts/filters/i18n_locals.js | 4 +- test/scripts/filters/meta_generator.js | 6 +- test/scripts/filters/new_post_path.js | 4 +- test/scripts/filters/post_permalink.js | 4 +- test/scripts/filters/render_post.js | 4 +- test/scripts/filters/save_database.js | 4 +- test/scripts/filters/titlecase.js | 4 +- test/scripts/generators/asset.js | 4 +- test/scripts/generators/page.js | 4 +- test/scripts/generators/post.js | 4 +- test/scripts/helpers/css.js | 4 +- test/scripts/helpers/date.js | 4 +- test/scripts/helpers/debug.js | 2 +- test/scripts/helpers/escape_html.js | 2 +- test/scripts/helpers/favicon_tag.js | 4 +- test/scripts/helpers/feed_tag.js | 2 +- test/scripts/helpers/fragment_cache.js | 4 +- test/scripts/helpers/full_url_for.js | 2 +- test/scripts/helpers/gravatar.js | 2 +- test/scripts/helpers/image_tag.js | 4 +- test/scripts/helpers/is.js | 4 +- test/scripts/helpers/js.js | 4 +- test/scripts/helpers/link_to.js | 4 +- test/scripts/helpers/list_archives.js | 4 +- test/scripts/helpers/list_categories.js | 4 +- test/scripts/helpers/list_posts.js | 4 +- test/scripts/helpers/list_tags.js | 8 +- test/scripts/helpers/mail_to.js | 4 +- test/scripts/helpers/markdown.js | 6 +- test/scripts/helpers/meta_generator.js | 4 +- test/scripts/helpers/number_format.js | 2 +- test/scripts/helpers/open_graph.js | 8 +- test/scripts/helpers/paginator.js | 4 +- test/scripts/helpers/partial.js | 6 +- test/scripts/helpers/relative_url.js | 2 +- test/scripts/helpers/render.js | 4 +- test/scripts/helpers/search_form.js | 2 +- test/scripts/helpers/tagcloud.js | 6 +- test/scripts/helpers/toc.js | 2 +- test/scripts/helpers/url_for.js | 4 +- test/scripts/hexo/hexo.js | 6 +- test/scripts/hexo/load_config.js | 6 +- test/scripts/hexo/load_database.js | 8 +- test/scripts/hexo/load_plugins.js | 4 +- test/scripts/hexo/load_theme_config.js | 4 +- test/scripts/hexo/locals.js | 2 +- test/scripts/hexo/multi_config_path.js | 4 +- test/scripts/hexo/post.js | 2 +- test/scripts/hexo/render.js | 2 +- test/scripts/hexo/router.js | 2 +- test/scripts/hexo/scaffold.js | 2 +- test/scripts/hexo/update_package.js | 4 +- test/scripts/hexo/validate_config.js | 6 +- test/scripts/models/asset.js | 2 +- test/scripts/models/cache.js | 2 +- test/scripts/models/category.js | 4 +- test/scripts/models/moment.js | 2 +- test/scripts/models/page.js | 4 +- test/scripts/models/post.js | 2 +- test/scripts/models/post_asset.js | 4 +- test/scripts/models/tag.js | 4 +- test/scripts/processors/asset.js | 6 +- test/scripts/processors/common.js | 2 +- test/scripts/processors/data.js | 4 +- test/scripts/processors/post.js | 6 +- test/scripts/renderers/json.js | 2 +- test/scripts/renderers/nunjucks.js | 2 +- test/scripts/renderers/plain.js | 2 +- test/scripts/renderers/yaml.js | 2 +- test/scripts/tags/asset_img.js | 4 +- test/scripts/tags/asset_link.js | 4 +- test/scripts/tags/asset_path.js | 4 +- test/scripts/tags/blockquote.js | 4 +- test/scripts/tags/code.js | 6 +- test/scripts/tags/iframe.js | 2 +- test/scripts/tags/img.js | 4 +- test/scripts/tags/include_code.js | 6 +- test/scripts/tags/link.js | 2 +- test/scripts/tags/post_link.js | 4 +- test/scripts/tags/post_path.js | 4 +- test/scripts/tags/pullquote.js | 4 +- test/scripts/theme/theme.js | 2 +- test/scripts/theme/view.js | 2 +- test/scripts/theme_processors/config.js | 8 +- test/scripts/theme_processors/i18n.js | 8 +- test/scripts/theme_processors/source.js | 8 +- test/scripts/theme_processors/view.js | 8 +- tsconfig.json | 19 ++ 280 files changed, 1469 insertions(+), 1237 deletions(-) rename lib/box/{file.js => file.ts} (64%) rename lib/box/{index.js => index.ts} (82%) rename lib/extend/{console.js => console.ts} (94%) rename lib/extend/{deployer.js => deployer.ts} (76%) rename lib/extend/{filter.js => filter.ts} (68%) rename lib/extend/{generator.js => generator.ts} (80%) rename lib/extend/{helper.js => helper.ts} (87%) delete mode 100644 lib/extend/index.js create mode 100644 lib/extend/index.ts rename lib/extend/{injector.js => injector.ts} (96%) rename lib/extend/{migrator.js => migrator.ts} (76%) rename lib/extend/{processor.js => processor.ts} (81%) rename lib/extend/{renderer.js => renderer.ts} (90%) rename lib/extend/{syntax_highlight.js => syntax_highlight.ts} (57%) rename lib/extend/{tag.js => tag.ts} (91%) rename lib/hexo/{default_config.js => default_config.ts} (97%) rename lib/hexo/{index.js => index.ts} (79%) rename lib/hexo/{load_config.js => load_config.ts} (84%) rename lib/hexo/{load_database.js => load_database.ts} (65%) rename lib/hexo/{load_plugins.js => load_plugins.ts} (90%) rename lib/hexo/{load_theme_config.js => load_theme_config.ts} (81%) rename lib/hexo/{locals.js => locals.ts} (92%) rename lib/hexo/{multi_config_path.js => multi_config_path.ts} (78%) rename lib/hexo/{post.js => post.ts} (92%) rename lib/hexo/{register_models.js => register_models.ts} (70%) rename lib/hexo/{render.js => render.ts} (93%) rename lib/hexo/{router.js => router.ts} (85%) rename lib/hexo/{scaffold.js => scaffold.ts} (87%) rename lib/hexo/{source.js => source.ts} (66%) rename lib/hexo/{update_package.js => update_package.ts} (58%) rename lib/hexo/{validate_config.js => validate_config.ts} (94%) rename lib/models/{asset.js => asset.ts} (65%) rename lib/models/{cache.js => cache.ts} (90%) rename lib/models/{category.js => category.ts} (88%) delete mode 100644 lib/models/data.js create mode 100644 lib/models/data.ts delete mode 100644 lib/models/index.js create mode 100644 lib/models/index.ts rename lib/models/{page.js => page.ts} (75%) rename lib/models/{post.js => post.ts} (93%) rename lib/models/{post_asset.js => post_asset.ts} (76%) delete mode 100644 lib/models/post_category.js create mode 100644 lib/models/post_category.ts delete mode 100644 lib/models/post_tag.js create mode 100644 lib/models/post_tag.ts rename lib/models/{tag.js => tag.ts} (90%) rename lib/models/types/{moment.js => moment.ts} (82%) rename lib/plugins/console/{clean.js => clean.ts} (62%) rename lib/plugins/console/{config.js => config.ts} (83%) rename lib/plugins/console/{deploy.js => deploy.ts} (83%) rename lib/plugins/console/{generate.js => generate.ts} (89%) rename lib/plugins/console/{index.js => index.ts} (98%) rename lib/plugins/console/list/{category.js => category.ts} (70%) rename lib/plugins/console/list/{common.js => common.ts} (71%) rename lib/plugins/console/list/{index.js => index.ts} (61%) rename lib/plugins/console/list/{page.js => page.ts} (71%) rename lib/plugins/console/list/{post.js => post.ts} (80%) rename lib/plugins/console/list/{route.js => route.ts} (92%) rename lib/plugins/console/list/{tag.js => tag.ts} (70%) rename lib/plugins/console/{migrate.js => migrate.ts} (86%) rename lib/plugins/console/{new.js => new.ts} (86%) rename lib/plugins/console/{publish.js => publish.ts} (76%) rename lib/plugins/console/{render.js => render.ts} (75%) rename lib/plugins/filter/after_post_render/{excerpt.js => excerpt.ts} (91%) rename lib/plugins/filter/after_post_render/{external_link.js => external_link.ts} (90%) rename lib/plugins/filter/after_post_render/{index.js => index.ts} (80%) rename lib/plugins/filter/after_render/{external_link.js => external_link.ts} (90%) rename lib/plugins/filter/after_render/{index.js => index.ts} (80%) rename lib/plugins/filter/after_render/{meta_generator.js => meta_generator.ts} (88%) rename lib/plugins/filter/before_exit/{index.js => index.ts} (70%) rename lib/plugins/filter/before_exit/{save_database.js => save_database.ts} (76%) rename lib/plugins/filter/before_generate/{index.js => index.ts} (71%) rename lib/plugins/filter/before_generate/{render_post.js => render_post.ts} (75%) rename lib/plugins/filter/before_post_render/{backtick_code_block.js => backtick_code_block.ts} (93%) rename lib/plugins/filter/before_post_render/{index.js => index.ts} (81%) rename lib/plugins/filter/before_post_render/{titlecase.js => titlecase.ts} (83%) rename lib/plugins/filter/{index.js => index.ts} (90%) rename lib/plugins/filter/{new_post_path.js => new_post_path.ts} (81%) rename lib/plugins/filter/{post_permalink.js => post_permalink.ts} (85%) rename lib/plugins/filter/template_locals/{i18n.js => i18n.ts} (90%) rename lib/plugins/filter/template_locals/{index.js => index.ts} (69%) rename lib/plugins/generator/{asset.js => asset.ts} (53%) rename lib/plugins/generator/{index.js => index.ts} (82%) rename lib/plugins/generator/{page.js => page.ts} (90%) rename lib/plugins/generator/{post.js => post.ts} (92%) rename lib/plugins/helper/{css.js => css.ts} (80%) rename lib/plugins/helper/{date.js => date.ts} (82%) rename lib/plugins/helper/{debug.js => debug.ts} (69%) rename lib/plugins/helper/{favicon_tag.js => favicon_tag.ts} (54%) rename lib/plugins/helper/{feed_tag.js => feed_tag.ts} (85%) delete mode 100644 lib/plugins/helper/format.js create mode 100644 lib/plugins/helper/format.ts rename lib/plugins/helper/{fragment_cache.js => fragment_cache.ts} (78%) delete mode 100755 lib/plugins/helper/full_url_for.js create mode 100644 lib/plugins/helper/full_url_for.ts delete mode 100644 lib/plugins/helper/gravatar.js create mode 100644 lib/plugins/helper/gravatar.ts delete mode 100644 lib/plugins/helper/image_tag.js create mode 100644 lib/plugins/helper/image_tag.ts rename lib/plugins/helper/{index.js => index.ts} (98%) rename lib/plugins/helper/{is.js => is.ts} (81%) rename lib/plugins/helper/{js.js => js.ts} (80%) delete mode 100644 lib/plugins/helper/link_to.js create mode 100644 lib/plugins/helper/link_to.ts rename lib/plugins/helper/{list_archives.js => list_archives.ts} (84%) rename lib/plugins/helper/{list_categories.js => list_categories.ts} (93%) rename lib/plugins/helper/{list_posts.js => list_posts.ts} (93%) rename lib/plugins/helper/{list_tags.js => list_tags.ts} (94%) rename lib/plugins/helper/{mail_to.js => mail_to.ts} (60%) rename lib/plugins/helper/{markdown.js => markdown.ts} (65%) rename lib/plugins/helper/{meta_generator.js => meta_generator.ts} (66%) mode change 100755 => 100644 rename lib/plugins/helper/{number_format.js => number_format.ts} (81%) rename lib/plugins/helper/{open_graph.js => open_graph.ts} (85%) rename lib/plugins/helper/{paginator.js => paginator.ts} (87%) rename lib/plugins/helper/{partial.js => partial.ts} (82%) delete mode 100644 lib/plugins/helper/relative_url.js create mode 100644 lib/plugins/helper/relative_url.ts delete mode 100644 lib/plugins/helper/render.js create mode 100644 lib/plugins/helper/render.ts rename lib/plugins/helper/{search_form.js => search_form.ts} (72%) rename lib/plugins/helper/{tagcloud.js => tagcloud.ts} (93%) rename lib/plugins/helper/{toc.js => toc.ts} (86%) delete mode 100644 lib/plugins/helper/url_for.js create mode 100644 lib/plugins/helper/url_for.ts rename lib/plugins/highlight/{highlight.js => highlight.ts} (98%) rename lib/plugins/highlight/{index.js => index.ts} (92%) rename lib/plugins/highlight/{prism.js => prism.ts} (98%) rename lib/plugins/injector/{index.js => index.ts} (66%) rename lib/plugins/processor/{asset.js => asset.ts} (88%) rename lib/plugins/processor/{common.js => common.ts} (71%) rename lib/plugins/processor/{data.js => data.ts} (83%) rename lib/plugins/processor/{index.js => index.ts} (84%) rename lib/plugins/processor/{post.js => post.ts} (94%) rename lib/plugins/renderer/{index.js => index.ts} (93%) rename lib/plugins/renderer/{json.js => json.ts} (58%) rename lib/plugins/renderer/{nunjucks.js => nunjucks.ts} (90%) rename lib/plugins/renderer/{plain.js => plain.ts} (53%) rename lib/plugins/renderer/{yaml.js => yaml.ts} (56%) rename lib/plugins/tag/{asset_img.js => asset_img.ts} (81%) rename lib/plugins/tag/{asset_link.js => asset_link.ts} (88%) rename lib/plugins/tag/{asset_path.js => asset_path.ts} (82%) rename lib/plugins/tag/{blockquote.js => blockquote.ts} (93%) rename lib/plugins/tag/{code.js => code.ts} (92%) rename lib/plugins/tag/{iframe.js => iframe.ts} (83%) rename lib/plugins/tag/{img.js => img.ts} (94%) rename lib/plugins/tag/{include_code.js => include_code.ts} (89%) rename lib/plugins/tag/{index.js => index.ts} (90%) rename lib/plugins/tag/{link.js => link.ts} (92%) rename lib/plugins/tag/{post_link.js => post_link.ts} (87%) rename lib/plugins/tag/{post_path.js => post_path.ts} (75%) rename lib/plugins/tag/{pullquote.js => pullquote.ts} (78%) rename lib/theme/{index.js => index.ts} (71%) rename lib/theme/processors/{config.js => config.ts} (64%) rename lib/theme/processors/{i18n.js => i18n.ts} (64%) rename lib/theme/processors/{source.js => source.ts} (73%) rename lib/theme/processors/{view.js => view.ts} (56%) rename lib/theme/{view.js => view.ts} (83%) create mode 100644 tsconfig.json diff --git a/.eslintrc.json b/.eslintrc.json index 2cf72c2756..98a0b413b2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,4 +1,13 @@ -{ - "extends": "hexo", - "root": true -} +{ + "root": true, + "extends": "hexo/ts.js", + "parserOptions": { + "sourceType": "module", + "ecmaVersion": 2020 + }, + "rules": { + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/no-var-requires": 0, + "node/no-missing-require": 0 + } +} diff --git a/.gitignore b/.gitignore index a62e2da0ac..67d6810998 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ package-lock.json coverage/ .tmp* .vscode +dist/ diff --git a/lib/box/file.js b/lib/box/file.ts similarity index 64% rename from lib/box/file.js rename to lib/box/file.ts index 87ae2ba5f2..6171e430d6 100644 --- a/lib/box/file.js +++ b/lib/box/file.ts @@ -1,8 +1,15 @@ -'use strict'; - -const { readFile, readFileSync, stat, statSync } = require('hexo-fs'); +import { readFile, readFileSync, stat, statSync } from 'hexo-fs'; class File { + public source: any; + public path: any; + public params: any; + public type: any; + static TYPE_CREATE: 'create'; + static TYPE_UPDATE: 'update'; + static TYPE_SKIP: 'skip'; + static TYPE_DELETE: 'delete'; + constructor({ source, path, params, type }) { this.source = source; this.path = path; @@ -32,4 +39,4 @@ File.TYPE_UPDATE = 'update'; File.TYPE_SKIP = 'skip'; File.TYPE_DELETE = 'delete'; -module.exports = File; +export = File; diff --git a/lib/box/index.js b/lib/box/index.ts similarity index 82% rename from lib/box/index.js rename to lib/box/index.ts index 2975570b8c..5dceb37784 100644 --- a/lib/box/index.js +++ b/lib/box/index.ts @@ -1,18 +1,35 @@ -'use strict'; - -const { join, sep } = require('path'); -const Promise = require('bluebird'); -const File = require('./file'); -const { Pattern, createSha1Hash } = require('hexo-util'); -const { createReadStream, readdir, stat, watch } = require('hexo-fs'); -const { magenta } = require('picocolors'); -const { EventEmitter } = require('events'); -const { isMatch, makeRe } = require('micromatch'); +import { join, sep } from 'path'; +import BlueBirdPromise from 'bluebird'; +import File from './file'; +import { Pattern, createSha1Hash } from 'hexo-util'; +import { createReadStream, readdir, stat, watch } from 'hexo-fs'; +import { magenta } from 'picocolors'; +import { EventEmitter } from 'events'; +import { isMatch, makeRe } from 'micromatch'; const defaultPattern = new Pattern(() => ({})); +interface Processor { + pattern: Pattern; + process: (file: File) => void; +} + class Box extends EventEmitter { - constructor(ctx, base, options) { + public options: any; + public context: any; + public base: any; + public processors: Processor[]; + public _processingFiles: any; + public watcher: any; + public Cache: any; + // TODO: replace runtime class _File + public File: any; + public ignore: any; + public source: any; + public emit: any; + public ctx: any; + + constructor(ctx, base, options?: object) { super(); this.options = Object.assign({ @@ -40,10 +57,13 @@ class Box extends EventEmitter { this.ignore = targets; this.options.ignored = targets.map(s => toRegExp(ctx, s)).filter(x => x); } + _createFileClass() { const ctx = this.context; class _File extends File { + public box: Box; + render(options) { return ctx.render.render({ path: this.source @@ -100,7 +120,7 @@ class Box extends EventEmitter { })); } - process(callback) { + process(callback?) { const { base, Cache, context: ctx } = this; return stat(base).then(stats => { @@ -121,7 +141,7 @@ class Box extends EventEmitter { _processFile(type, path) { if (this._processingFiles[path]) { - return Promise.resolve(); + return BlueBirdPromise.resolve(); } this._processingFiles[path] = true; @@ -133,7 +153,7 @@ class Box extends EventEmitter { path }); - return Promise.reduce(this.processors, (count, processor) => { + return BlueBirdPromise.reduce(this.processors, (count, processor) => { const params = processor.pattern.match(path); if (!params) return count; @@ -144,7 +164,7 @@ class Box extends EventEmitter { type }); - return Reflect.apply(Promise.method(processor.process), ctx, [file]) + return Reflect.apply(BlueBirdPromise.method(processor.process), ctx, [file]) .thenReturn(count + 1); }, 0).then(count => { if (count) { @@ -164,7 +184,7 @@ class Box extends EventEmitter { watch(callback) { if (this.isWatching()) { - return Promise.reject(new Error('Watcher has already started.')).asCallback(callback); + return BlueBirdPromise.reject(new Error('Watcher has already started.')).asCallback(callback); } const { base } = this; @@ -218,7 +238,7 @@ function getHash(path) { const src = createReadStream(path); const hasher = createSha1Hash(); - const finishedPromise = new Promise((resolve, reject) => { + const finishedPromise = new BlueBirdPromise((resolve, reject) => { src.once('error', reject); src.once('end', resolve); }); @@ -247,9 +267,9 @@ function isIgnoreMatch(path, ignore) { } function readDirWalker(ctx, base, results, ignore, prefix) { - if (isIgnoreMatch(base, ignore)) return Promise.resolve(); + if (isIgnoreMatch(base, ignore)) return BlueBirdPromise.resolve(); - return Promise.map(readdir(base).catch(err => { + return BlueBirdPromise.map(readdir(base).catch(err => { ctx.log.error({ err }, 'Failed to read directory: %s', base); if (err && err.code === 'ENOENT') return []; throw err; @@ -272,4 +292,4 @@ function readDirWalker(ctx, base, results, ignore, prefix) { }); } -module.exports = Box; +export = Box; diff --git a/lib/extend/console.js b/lib/extend/console.ts similarity index 94% rename from lib/extend/console.js rename to lib/extend/console.ts index 3c2765ddac..6a977a25a8 100644 --- a/lib/extend/console.js +++ b/lib/extend/console.ts @@ -1,7 +1,5 @@ -'use strict'; - -const Promise = require('bluebird'); -const abbrev = require('abbrev'); +import Promise from 'bluebird'; +import abbrev from 'abbrev'; /** * Console plugin option @@ -12,6 +10,9 @@ const abbrev = require('abbrev'); */ class Console { + public store: any; + public alias: any; + constructor() { this.store = {}; this.alias = {}; @@ -82,4 +83,4 @@ class Console { } } -module.exports = Console; +export = Console; diff --git a/lib/extend/deployer.js b/lib/extend/deployer.ts similarity index 76% rename from lib/extend/deployer.js rename to lib/extend/deployer.ts index 4653662f08..b743071fdb 100644 --- a/lib/extend/deployer.js +++ b/lib/extend/deployer.ts @@ -1,8 +1,8 @@ -'use strict'; - -const Promise = require('bluebird'); +import Promise from 'bluebird'; class Deployer { + public store: any; + constructor() { this.store = {}; } @@ -11,11 +11,11 @@ class Deployer { return this.store; } - get(name) { + get(name: string) { return this.store[name]; } - register(name, fn) { + register(name: string, fn) { if (!name) throw new TypeError('name is required'); if (typeof fn !== 'function') throw new TypeError('fn must be a function'); @@ -29,4 +29,4 @@ class Deployer { } } -module.exports = Deployer; +export = Deployer; diff --git a/lib/extend/filter.js b/lib/extend/filter.ts similarity index 68% rename from lib/extend/filter.js rename to lib/extend/filter.ts index 520b22668e..eba129cc1b 100644 --- a/lib/extend/filter.js +++ b/lib/extend/filter.ts @@ -1,6 +1,4 @@ -'use strict'; - -const Promise = require('bluebird'); +import Promise from 'bluebird'; const typeAlias = { pre: 'before_post_render', @@ -8,20 +6,39 @@ const typeAlias = { 'after_render:html': '_after_html_render' }; +interface FilterOptions { + context?: any; + args?: any; +} + +interface StoreFunction { + (...args: any[]): any; + priority?: number; +} + +interface Store { + [key: string]: StoreFunction[] +} + class Filter { + public store: Store; + constructor() { this.store = {}; } - list(type) { + list(): Store; + list(type: string): StoreFunction[]; + list(type?: string) { if (!type) return this.store; return this.store[type] || []; } - register(type, fn, priority) { + register(fn: StoreFunction, priority: number); + register(type?: string | StoreFunction, fn?: StoreFunction | number, priority?: number) { if (!priority) { if (typeof type === 'function') { - priority = fn; + priority = fn as number; fn = type; type = 'after_post_render'; } @@ -29,11 +46,11 @@ class Filter { if (typeof fn !== 'function') throw new TypeError('fn must be a function'); - type = typeAlias[type] || type; + type = typeAlias[type as string] || type; priority = priority == null ? 10 : priority; - const store = this.store[type] || []; - this.store[type] = store; + const store = this.store[type as string] || []; + this.store[type as string] = store; fn.priority = priority; store.push(fn); @@ -41,7 +58,7 @@ class Filter { store.sort((a, b) => a.priority - b.priority); } - unregister(type, fn) { + unregister(type: string, fn: StoreFunction) { if (!type) throw new TypeError('type is required'); if (typeof fn !== 'function') throw new TypeError('fn must be a function'); @@ -55,7 +72,7 @@ class Filter { if (index !== -1) list.splice(index, 1); } - exec(type, data, options = {}) { + exec(type: string, data, options: FilterOptions = {}) { const filters = this.list(type); if (filters.length === 0) return Promise.resolve(data); @@ -70,7 +87,7 @@ class Filter { })).then(() => args[0]); } - execSync(type, data, options = {}) { + execSync(type: string, data, options: FilterOptions = {}) { const filters = this.list(type); const filtersLen = filters.length; if (filtersLen === 0) return data; @@ -89,4 +106,4 @@ class Filter { } } -module.exports = Filter; +export = Filter; diff --git a/lib/extend/generator.js b/lib/extend/generator.ts similarity index 80% rename from lib/extend/generator.js rename to lib/extend/generator.ts index 6a0c087703..41a4a07b12 100644 --- a/lib/extend/generator.js +++ b/lib/extend/generator.ts @@ -1,8 +1,9 @@ -'use strict'; - -const Promise = require('bluebird'); +import Promise from 'bluebird'; class Generator { + public id: any; + public store: any; + constructor() { this.id = 0; this.store = {}; @@ -12,7 +13,7 @@ class Generator { return this.store; } - get(name) { + get(name: string) { return this.store[name]; } @@ -31,4 +32,4 @@ class Generator { } } -module.exports = Generator; +export = Generator; diff --git a/lib/extend/helper.js b/lib/extend/helper.ts similarity index 87% rename from lib/extend/helper.js rename to lib/extend/helper.ts index d8c6156d4c..fe0500fdd1 100644 --- a/lib/extend/helper.js +++ b/lib/extend/helper.ts @@ -1,6 +1,6 @@ -'use strict'; - class Helper { + public store: any; + constructor() { this.store = {}; } @@ -17,7 +17,7 @@ class Helper { * @param {String} name - The name of the helper plugin * @returns {Function} */ - get(name) { + get(name: string) { return this.store[name]; } @@ -26,7 +26,7 @@ class Helper { * @param {String} name - The name of the helper plugin * @param {Function} fn - The helper plugin function */ - register(name, fn) { + register(name: string, fn) { if (!name) throw new TypeError('name is required'); if (typeof fn !== 'function') throw new TypeError('fn must be a function'); @@ -34,4 +34,4 @@ class Helper { } } -module.exports = Helper; +export = Helper; diff --git a/lib/extend/index.js b/lib/extend/index.js deleted file mode 100644 index f4ddd1a2e5..0000000000 --- a/lib/extend/index.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; - -const Console = require('./console'); -const Deployer = require('./deployer'); -const Filter = require('./filter'); -const Generator = require('./generator'); -const Helper = require('./helper'); -const Highlight = require('./syntax_highlight'); -const Injector = require('./injector'); -const Migrator = require('./migrator'); -const Processor = require('./processor'); -const Renderer = require('./renderer'); -const Tag = require('./tag'); - -module.exports = { - Console, Deployer, Filter, Generator, Helper, Highlight, Injector, Migrator, Processor, Renderer, Tag -}; diff --git a/lib/extend/index.ts b/lib/extend/index.ts new file mode 100644 index 0000000000..2c4dac82bc --- /dev/null +++ b/lib/extend/index.ts @@ -0,0 +1,11 @@ +export { default as Console } from './console'; +export { default as Deployer } from './deployer'; +export { default as Filter } from './filter'; +export { default as Generator } from './generator'; +export { default as Helper } from './helper'; +export { default as Highlight } from './syntax_highlight'; +export { default as Injector } from './injector'; +export { default as Migrator } from './migrator'; +export { default as Processor } from './processor'; +export { default as Renderer } from './renderer'; +export { default as Tag } from './tag'; diff --git a/lib/extend/injector.js b/lib/extend/injector.ts similarity index 96% rename from lib/extend/injector.js rename to lib/extend/injector.ts index 74689d3202..7802152efd 100644 --- a/lib/extend/injector.js +++ b/lib/extend/injector.ts @@ -1,8 +1,10 @@ -'use strict'; - -const { Cache } = require('hexo-util'); +import { Cache } from 'hexo-util'; class Injector { + public store: any; + public cache: any; + public page: any; + constructor() { this.store = { head_begin: {}, @@ -99,4 +101,4 @@ class Injector { } } -module.exports = Injector; +export = Injector; diff --git a/lib/extend/migrator.js b/lib/extend/migrator.ts similarity index 76% rename from lib/extend/migrator.js rename to lib/extend/migrator.ts index 12a25bc5a6..94e725dc0c 100644 --- a/lib/extend/migrator.js +++ b/lib/extend/migrator.ts @@ -1,8 +1,8 @@ -'use strict'; - -const Promise = require('bluebird'); +import Promise from 'bluebird'; class Migrator { + public store: any; + constructor() { this.store = {}; } @@ -11,11 +11,11 @@ class Migrator { return this.store; } - get(name) { + get(name: string) { return this.store[name]; } - register(name, fn) { + register(name: string, fn) { if (!name) throw new TypeError('name is required'); if (typeof fn !== 'function') throw new TypeError('fn must be a function'); @@ -29,4 +29,4 @@ class Migrator { } } -module.exports = Migrator; +export = Migrator; diff --git a/lib/extend/processor.js b/lib/extend/processor.ts similarity index 81% rename from lib/extend/processor.js rename to lib/extend/processor.ts index da2efbd7e6..b3bcb8e544 100644 --- a/lib/extend/processor.js +++ b/lib/extend/processor.ts @@ -1,9 +1,9 @@ -'use strict'; - -const Promise = require('bluebird'); -const { Pattern } = require('hexo-util'); +import Promise from 'bluebird'; +import { Pattern } from 'hexo-util'; class Processor { + public store: any; + constructor() { this.store = []; } @@ -35,4 +35,4 @@ class Processor { } } -module.exports = Processor; +export = Processor; diff --git a/lib/extend/renderer.js b/lib/extend/renderer.ts similarity index 90% rename from lib/extend/renderer.js rename to lib/extend/renderer.ts index 994b1270f9..e2782dfdba 100644 --- a/lib/extend/renderer.js +++ b/lib/extend/renderer.ts @@ -1,7 +1,5 @@ -'use strict'; - -const { extname } = require('path'); -const Promise = require('bluebird'); +import { extname } from 'path'; +import Promise from 'bluebird'; const getExtname = str => { if (typeof str !== 'string') return ''; @@ -11,6 +9,9 @@ const getExtname = str => { }; class Renderer { + public store: any; + public storeSync: any; + constructor() { this.store = {}; this.storeSync = {}; @@ -20,7 +21,7 @@ class Renderer { return sync ? this.storeSync : this.store; } - get(name, sync) { + get(name, sync?) { const store = this[sync ? 'storeSync' : 'store']; return store[getExtname(name)] || store[name]; @@ -63,4 +64,4 @@ class Renderer { } } -module.exports = Renderer; +export = Renderer; diff --git a/lib/extend/syntax_highlight.js b/lib/extend/syntax_highlight.ts similarity index 57% rename from lib/extend/syntax_highlight.js rename to lib/extend/syntax_highlight.ts index 56d83ba2a8..22d9371a5e 100644 --- a/lib/extend/syntax_highlight.js +++ b/lib/extend/syntax_highlight.ts @@ -1,21 +1,35 @@ -'use strict'; +interface Options { + context?: any; + args?: any; +} + +interface StoreFunction { + (...args: any[]): any; + priority?: number; +} + +interface Store { + [key: string]: StoreFunction +} class SyntaxHighlight { + public store: Store; + constructor() { this.store = {}; } - register(name, fn) { + register(name: string, fn: StoreFunction) { if (typeof fn !== 'function') throw new TypeError('fn must be a function'); this.store[name] = fn; } - query(name) { + query(name: string) { return name && this.store[name]; } - exec(name, options) { + exec(name: string, options: Options) { const fn = this.store[name]; if (!fn) throw new TypeError(`syntax highlighter ${name} is not registered`); @@ -26,4 +40,4 @@ class SyntaxHighlight { } } -module.exports = SyntaxHighlight; +export = SyntaxHighlight; diff --git a/lib/extend/tag.js b/lib/extend/tag.ts similarity index 91% rename from lib/extend/tag.js rename to lib/extend/tag.ts index f633781513..b2bcd2fcfd 100644 --- a/lib/extend/tag.js +++ b/lib/extend/tag.ts @@ -1,14 +1,15 @@ -'use strict'; - -const { stripIndent } = require('hexo-util'); -const { cyan, magenta, red, bold } = require('picocolors'); -const { Environment } = require('nunjucks'); -const Promise = require('bluebird'); +import { stripIndent } from 'hexo-util'; +import { cyan, magenta, red, bold } from 'picocolors'; +import { Environment } from 'nunjucks'; +import Promise from 'bluebird'; const rSwigRawFullBlock = /{% *raw *%}/; const rCodeTag = /]*>[\s\S]+?<\/code>/g; const escapeSwigTag = str => str.replace(/{/g, '{').replace(/}/g, '}'); class NunjucksTag { + public tags: any; + public fn: any; + constructor(name, fn) { this.tags = [name]; this.fn = fn; @@ -49,11 +50,11 @@ class NunjucksTag { return node; } - run(context, args) { + run(context, args, body, callback) { return this._run(context, args, ''); } - _run(context, args, body) { + _run(context, args, body): any { return Reflect.apply(this.fn, context.ctx, [args, body]); } } @@ -77,7 +78,7 @@ class NunjucksBlock extends NunjucksTag { return body; } - run(context, args, body) { + run(context, args, body, callback) { return this._run(context, args, trimBody(body)); } } @@ -153,6 +154,12 @@ const getContext = (lines, errLine, location, type) => { return message; }; +class NunjucksError extends Error { + line?: number; + location?: string; + type?: string; +} + /** * Provide context for Nunjucks error * @param {Error} err Nunjucks error @@ -170,7 +177,7 @@ const formatNunjucksError = (err, input, source = '') => { // trim useless info from Nunjucks Error const splited = err.message.split('\n'); - const e = new Error(); + const e = new NunjucksError(); e.name = 'Nunjucks Error'; e.line = errLine; e.location = splited[0]; @@ -180,6 +187,9 @@ const formatNunjucksError = (err, input, source = '') => { }; class Tag { + public env: any; + public source: any; + constructor() { this.env = new Environment(null, { autoescape: false @@ -225,7 +235,7 @@ class Tag { if (env.hasExtension(name)) env.removeExtension(name); } - render(str, options = {}, callback) { + render(str, options: { source?: string } = {}, callback) { if (!callback && typeof options === 'function') { callback = options; options = {}; @@ -252,4 +262,4 @@ class Tag { } } -module.exports = Tag; +export = Tag; diff --git a/lib/hexo/default_config.js b/lib/hexo/default_config.ts similarity index 97% rename from lib/hexo/default_config.js rename to lib/hexo/default_config.ts index 3c887a2400..379f80737e 100644 --- a/lib/hexo/default_config.js +++ b/lib/hexo/default_config.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = { +export = { // Site title: 'Hexo', subtitle: '', diff --git a/lib/hexo/index.js b/lib/hexo/index.ts similarity index 79% rename from lib/hexo/index.js rename to lib/hexo/index.ts index 8f6fe53344..023f78f81d 100644 --- a/lib/hexo/index.js +++ b/lib/hexo/index.ts @@ -1,29 +1,41 @@ -'use strict'; - -const Promise = require('bluebird'); -const { sep, join, dirname } = require('path'); -const tildify = require('tildify'); -const Database = require('warehouse').default; -const { magenta, underline } = require('picocolors'); -const { EventEmitter } = require('events'); -const { readFile } = require('hexo-fs'); -const Module = require('module'); -const { runInThisContext } = require('vm'); -const { version } = require('../../package.json'); -const { logger } = require('hexo-log'); -const { Console, Deployer, Filter, Generator, Helper, Highlight, Injector, Migrator, Processor, Renderer, Tag } = require('../extend'); -const Render = require('./render'); -const registerModels = require('./register_models'); -const Post = require('./post'); -const Scaffold = require('./scaffold'); -const Source = require('./source'); -const Router = require('./router'); -const Theme = require('../theme'); -const Locals = require('./locals'); -const defaultConfig = require('./default_config'); -const loadDatabase = require('./load_database'); -const multiConfigPath = require('./multi_config_path'); -const { deepMerge, full_url_for } = require('hexo-util'); +import Promise from 'bluebird'; +import { sep, join, dirname } from 'path'; +import tildify from 'tildify'; +import Database from 'warehouse'; +import { magenta, underline } from 'picocolors'; +import { EventEmitter } from 'events'; +import { readFile } from 'hexo-fs'; +import Module from 'module'; +import { runInThisContext } from 'vm'; +const {version} = require('../../package.json'); +import logger from 'hexo-log'; + +import { + Console, + Deployer, + Filter, + Generator, + Helper, + Highlight, + Injector, + Migrator, + Processor, + Renderer, + Tag +} from '../extend'; + +import Render from './render'; +import registerModels from './register_models'; +import Post from './post'; +import Scaffold from './scaffold'; +import Source from './source'; +import Router from './router'; +import Theme from '../theme'; +import Locals from './locals'; +import defaultConfig from './default_config'; +import loadDatabase from './load_database'; +import multiConfigPath from './multi_config_path'; +import { deepMerge, full_url_for } from 'hexo-util'; let resolveSync; // = require('resolve'); const libDir = dirname(__dirname); @@ -81,20 +93,82 @@ const createLoadThemeRoute = function(generatorResult, locals, ctx) { }; }; -function debounce(func, wait) { - let timeout; +function debounce(func: () => void, wait: number) { + let timeout: NodeJS.Timeout; return function() { - const context = this; - const args = arguments; clearTimeout(timeout); timeout = setTimeout(() => { - func.apply(context, args); + func.apply(this); }, wait); }; } +interface Args { + debug?: any; + safe?: any; + silent?: any; + _?: any[]; + output?: any; + config?: any; +} + +interface Query { + date?: any; + published?: boolean; +} + +// Node.js internal APIs +declare module 'module' { + function _nodeModulePaths(path: string): string[]; + function _resolveFilename(request: string, parent: Module, isMain?: any, options?: any): string; + const _extensions: NodeJS.RequireExtensions, + _cache: any; +} + class Hexo extends EventEmitter { - constructor(base = process.cwd(), args = {}) { + public base_dir: any; + public public_dir: any; + public source_dir: any; + public plugin_dir: any; + public script_dir: any; + public scaffold_dir: any; + public theme_dir: any; + public theme_script_dir: any; + public env: any; + public extend: any; + public config: any; + public log: any; + public render: any; + public route: any; + public post: any; + public scaffold: any; + public _dbLoaded: any; + public _isGenerating: any; + public database: Database; + public config_path: any; + public source: any; + public theme: any; + public locals: any; + public version: any; + public emit: any; + public _watchBox: any; + public page: any; + public path: any; + public url: any; + public layout: any; + public view_dir: any; + public site: any; + public args: any; + public cache: any; + public alias: any; + public data: any; + public lib_dir: string; + public core_dir: string; + static lib_dir: string; + static core_dir: string; + static version: string; + + constructor(base = process.cwd(), args: Args = {}) { super(); this.base_dir = base + sep; @@ -169,7 +243,7 @@ class Hexo extends EventEmitter { this.source = new Source(this); this.theme = new Theme(this); - this.locals = new Locals(this); + this.locals = new Locals(); this._bindLocals(); } @@ -178,7 +252,7 @@ class Hexo extends EventEmitter { const { locals } = this; locals.set('posts', () => { - const query = {}; + const query: Query = {}; if (!this.config.future) { query.date = { $lte: Date.now() }; @@ -192,7 +266,7 @@ class Hexo extends EventEmitter { }); locals.set('pages', () => { - const query = {}; + const query: Query = {}; if (!this.config.future) { query.date = { $lte: Date.now() }; @@ -229,7 +303,7 @@ class Hexo extends EventEmitter { require('../plugins/injector')(this); require('../plugins/processor')(this); require('../plugins/renderer')(this); - require('../plugins/tag')(this); + require('../plugins/tag').default(this); // Load config return Promise.each([ @@ -251,7 +325,8 @@ class Hexo extends EventEmitter { const c = this.extend.console.get(name); - if (c) return Reflect.apply(c, this, [args]).asCallback(callback); + // eslint-disable-next-line no-extra-parens + if (c) return (Reflect.apply(c, this, [args]) as any).asCallback(callback); return Promise.reject(new Error(`Console \`${name}\` has not been registered yet!`)); } @@ -277,7 +352,7 @@ class Hexo extends EventEmitter { } } - loadPlugin(path, callback) { + loadPlugin(path: string, callback: (...args: any[]) => any) { return readFile(path).then(script => { // Based on: https://github.com/joyent/node/blob/v0.10.33/src/node.js#L516 const module = new Module(path); @@ -372,6 +447,19 @@ class Hexo extends EventEmitter { const localsObj = this.locals.toObject(); class Locals { + page: { + path: string; + }; + path: string; + url: string; + config: object; + theme: object; + layout: string; + env: any; + view_dir: string; + site: object; + cache?: boolean; + constructor(path, locals) { this.page = { ...locals }; if (this.page.path == null) this.page.path = path; @@ -439,7 +527,7 @@ class Hexo extends EventEmitter { }); } - _generate(options = {}) { + _generate(options: { cache?: boolean } = {}) { if (this._isGenerating) return; const useCache = options.cache; @@ -492,4 +580,4 @@ Hexo.prototype.core_dir = Hexo.core_dir; Hexo.version = version; Hexo.prototype.version = Hexo.version; -module.exports = Hexo; +export = Hexo; diff --git a/lib/hexo/load_config.js b/lib/hexo/load_config.ts similarity index 84% rename from lib/hexo/load_config.js rename to lib/hexo/load_config.ts index 81528e765c..231e285f02 100644 --- a/lib/hexo/load_config.js +++ b/lib/hexo/load_config.ts @@ -1,15 +1,13 @@ -'use strict'; - -const { sep, resolve, join, parse } = require('path'); -const tildify = require('tildify'); -const Theme = require('../theme'); -const Source = require('./source'); -const { exists, readdir } = require('hexo-fs'); -const { magenta } = require('picocolors'); -const { deepMerge } = require('hexo-util'); -const validateConfig = require('./validate_config'); - -module.exports = async ctx => { +import { sep, resolve, join, parse } from 'path'; +import tildify from 'tildify'; +import Theme from '../theme'; +import Source from './source'; +import { exists, readdir } from 'hexo-fs'; +import { magenta } from 'picocolors'; +import { deepMerge } from 'hexo-util'; +import validateConfig from './validate_config'; + +export = async ctx => { if (!ctx.env.init) return; const baseDir = ctx.base_dir; diff --git a/lib/hexo/load_database.js b/lib/hexo/load_database.ts similarity index 65% rename from lib/hexo/load_database.js rename to lib/hexo/load_database.ts index b3d59a036e..c64719c929 100644 --- a/lib/hexo/load_database.js +++ b/lib/hexo/load_database.ts @@ -1,16 +1,14 @@ -'use strict'; +import { exists, unlink } from 'hexo-fs'; +import Promise from 'bluebird'; -const fs = require('hexo-fs'); -const Promise = require('bluebird'); - -module.exports = ctx => { +export = ctx => { if (ctx._dbLoaded) return Promise.resolve(); const db = ctx.database; const { path } = db.options; const { log } = ctx; - return fs.exists(path).then(exist => { + return exists(path).then(exist => { if (!exist) return; log.debug('Loading database.'); @@ -19,6 +17,6 @@ module.exports = ctx => { ctx._dbLoaded = true; }).catch(() => { log.error('Database load failed. Deleting database.'); - return fs.unlink(path); + return unlink(path); }); }; diff --git a/lib/hexo/load_plugins.js b/lib/hexo/load_plugins.ts similarity index 90% rename from lib/hexo/load_plugins.js rename to lib/hexo/load_plugins.ts index 010127c74e..c1dcb29067 100644 --- a/lib/hexo/load_plugins.js +++ b/lib/hexo/load_plugins.ts @@ -1,11 +1,9 @@ -'use strict'; +import { join } from 'path'; +import { exists, readFile, listDir } from 'hexo-fs'; +import Promise from 'bluebird'; +import { magenta } from 'picocolors'; -const { join } = require('path'); -const { exists, readFile, listDir } = require('hexo-fs'); -const Promise = require('bluebird'); -const { magenta } = require('picocolors'); - -module.exports = ctx => { +export = ctx => { if (!ctx.env.init || ctx.env.safe) return; return loadModules(ctx).then(() => loadScripts(ctx)); @@ -20,7 +18,7 @@ function loadModuleList(ctx, basedir) { // Read package.json and find dependencies return readFile(packagePath).then(content => { - const json = JSON.parse(content); + const json = JSON.parse(content as string); const deps = Object.keys(json.dependencies || {}); const devDeps = Object.keys(json.devDependencies || {}); diff --git a/lib/hexo/load_theme_config.js b/lib/hexo/load_theme_config.ts similarity index 81% rename from lib/hexo/load_theme_config.js rename to lib/hexo/load_theme_config.ts index 1abb35d842..57a28adb41 100644 --- a/lib/hexo/load_theme_config.js +++ b/lib/hexo/load_theme_config.ts @@ -1,12 +1,10 @@ -'use strict'; +import { join, parse } from 'path'; +import tildify from 'tildify'; +import { exists, readdir } from 'hexo-fs'; +import { magenta } from 'picocolors'; +import { deepMerge } from 'hexo-util'; -const { join, parse } = require('path'); -const tildify = require('tildify'); -const { exists, readdir } = require('hexo-fs'); -const { magenta } = require('picocolors'); -const { deepMerge } = require('hexo-util'); - -module.exports = ctx => { +export = ctx => { if (!ctx.env.init) return; if (!ctx.config.theme) return; diff --git a/lib/hexo/locals.js b/lib/hexo/locals.ts similarity index 92% rename from lib/hexo/locals.js rename to lib/hexo/locals.ts index dfdc9a772c..468dabe26f 100644 --- a/lib/hexo/locals.js +++ b/lib/hexo/locals.ts @@ -1,8 +1,9 @@ -'use strict'; - -const { Cache } = require('hexo-util'); +import { Cache } from 'hexo-util'; class Locals { + public cache: any; + public getters: any; + constructor() { this.cache = new Cache(); this.getters = {}; @@ -61,4 +62,4 @@ class Locals { } } -module.exports = Locals; +export = Locals; diff --git a/lib/hexo/multi_config_path.js b/lib/hexo/multi_config_path.ts similarity index 78% rename from lib/hexo/multi_config_path.js rename to lib/hexo/multi_config_path.ts index 7d81d67643..8d140d3569 100644 --- a/lib/hexo/multi_config_path.js +++ b/lib/hexo/multi_config_path.ts @@ -1,11 +1,9 @@ -'use strict'; +import { isAbsolute, resolve, join, extname } from 'path'; +import { existsSync, readFileSync, writeFileSync } from 'hexo-fs'; +import yml from 'js-yaml'; +import { deepMerge } from 'hexo-util'; -const { isAbsolute, resolve, join, extname } = require('path'); -const fs = require('hexo-fs'); -const yml = require('js-yaml'); -const { deepMerge } = require('hexo-util'); - -module.exports = ctx => function multiConfigPath(base, configPaths, outputDir) { +export = ctx => function multiConfigPath(base, configPaths, outputDir) { const { log } = ctx; const defaultPath = join(base, '_config.yml'); @@ -22,7 +20,7 @@ module.exports = ctx => function multiConfigPath(base, configPaths, outputDir) { // only one config let configPath = isAbsolute(configPaths) ? configPaths : resolve(base, configPaths); - if (!fs.existsSync(configPath)) { + if (!existsSync(configPath)) { log.w(`Config file ${configPaths} not found, using default.`); configPath = defaultPath; } @@ -38,13 +36,13 @@ module.exports = ctx => function multiConfigPath(base, configPaths, outputDir) { for (let i = 0; i < numPaths; i++) { const configPath = isAbsolute(paths[i]) ? paths[i] : join(base, paths[i]); - if (!fs.existsSync(configPath)) { + if (!existsSync(configPath)) { log.w(`Config file ${paths[i]} not found.`); continue; } // files read synchronously to ensure proper overwrite order - const file = fs.readFileSync(configPath); + const file = readFileSync(configPath); const ext = extname(paths[i]).toLowerCase(); if (ext === '.yml') { @@ -70,7 +68,7 @@ module.exports = ctx => function multiConfigPath(base, configPaths, outputDir) { log.d(`Writing _multiconfig.yml to ${outputPath}`); - fs.writeFileSync(outputPath, yml.dump(combinedConfig)); + writeFileSync(outputPath, yml.dump(combinedConfig)); // write file and return path return outputPath; diff --git a/lib/hexo/post.js b/lib/hexo/post.ts similarity index 92% rename from lib/hexo/post.js rename to lib/hexo/post.ts index 2df362d2fa..6eda66cc90 100644 --- a/lib/hexo/post.js +++ b/lib/hexo/post.ts @@ -1,14 +1,12 @@ -'use strict'; - -const assert = require('assert'); -const moment = require('moment'); -const Promise = require('bluebird'); -const { join, extname, basename } = require('path'); -const { magenta } = require('picocolors'); -const { load } = require('js-yaml'); -const { slugize, escapeRegExp } = require('hexo-util'); -const { copyDir, exists, listDir, mkdirs, readFile, rmdir, unlink, writeFile } = require('hexo-fs'); -const { parse: yfmParse, split: yfmSplit, stringify: yfmStringify } = require('hexo-front-matter'); +import assert from 'assert'; +import moment from 'moment'; +import Promise from 'bluebird'; +import { join, extname, basename } from 'path'; +import { magenta } from 'picocolors'; +import { load } from 'js-yaml'; +import { slugize, escapeRegExp } from 'hexo-util'; +import { copyDir, exists, listDir, mkdirs, readFile, rmdir, unlink, writeFile } from 'hexo-fs'; +import { parse as yfmParse, split as yfmSplit, stringify as yfmStringify } from 'hexo-front-matter'; const preservedKeys = ['title', 'slug', 'path', 'layout', 'date', 'content']; const rHexoPostRenderEscape = /([\s\S]+?)<\/hexoPostRenderCodeBlock>/g; @@ -30,6 +28,9 @@ const isNonWhiteSpaceChar = char => char !== '\r' && char !== ' '; class PostRenderEscape { + public stored: any; + public length: any; + constructor() { this.stored = []; } @@ -217,12 +218,30 @@ const createAssetFolder = (path, assetFolder) => { }); }; +interface Result { + path?: string; + content?: string; +} + +interface Data { + engine?: string; + content?: string; + disableNunjucks?: boolean; + markdown?: object; + source?: string; +} + class Post { + public context: any; + public config: any; + public tag: any; + public separator: any; + constructor(context) { this.context = context; } - create(data, replace, callback) { + create(data, replace, callback?) { if (!callback && typeof replace === 'function') { callback = replace; replace = false; @@ -245,7 +264,7 @@ class Post { ]).spread((path, content) => { const result = { path, content }; - return Promise.all([ + return Promise.all([ // Write content to file writeFile(path, content), // Create asset folder @@ -323,7 +342,7 @@ class Post { data.slug = slug; const regex = new RegExp(`^${escapeRegExp(slug)}(?:[^\\/\\\\]+)`); let src = ''; - const result = {}; + const result: Result = {}; data.layout = (data.layout || config.default_layout).toLowerCase(); @@ -361,7 +380,7 @@ class Post { }).thenReturn(result).asCallback(callback); } - render(source, data = {}, callback) { + render(source, data: Data = {}, callback) { const ctx = this.context; const { config } = ctx; const { tag } = ctx.extend; @@ -418,7 +437,7 @@ class Post { data.content = cacheObj.escapeAllSwigTags(data.content); } - const options = data.markdown || {}; + const options: { highlight?: boolean; } = data.markdown || {}; if (!config.syntax_highlighter) options.highlight = null; ctx.log.debug('Rendering post: %s', magenta(source)); @@ -448,4 +467,4 @@ class Post { } } -module.exports = Post; +export = Post; diff --git a/lib/hexo/register_models.js b/lib/hexo/register_models.ts similarity index 70% rename from lib/hexo/register_models.js rename to lib/hexo/register_models.ts index 6245e122a1..864e4e3631 100644 --- a/lib/hexo/register_models.js +++ b/lib/hexo/register_models.ts @@ -1,8 +1,6 @@ -'use strict'; +import * as models from '../models'; -const models = require('../models'); - -module.exports = ctx => { +export = ctx => { const db = ctx.database; const keys = Object.keys(models); diff --git a/lib/hexo/render.js b/lib/hexo/render.ts similarity index 93% rename from lib/hexo/render.js rename to lib/hexo/render.ts index 802d1b38f0..a25d152314 100644 --- a/lib/hexo/render.js +++ b/lib/hexo/render.ts @@ -1,8 +1,6 @@ -'use strict'; - -const { extname } = require('path'); -const Promise = require('bluebird'); -const { readFile, readFileSync } = require('hexo-fs'); +import { extname } from 'path'; +import Promise from 'bluebird'; +import { readFile, readFileSync } from 'hexo-fs'; const getExtname = str => { if (typeof str !== 'string') return ''; @@ -26,6 +24,9 @@ const toString = (result, options) => { }; class Render { + public context: any; + public renderer: any; + constructor(ctx) { this.context = ctx; this.renderer = ctx.extend.renderer; @@ -43,7 +44,7 @@ class Render { return this.renderer.getOutput(path); } - getRenderer(ext, sync) { + getRenderer(ext, sync?) { return this.renderer.get(ext, sync); } @@ -131,4 +132,4 @@ class Render { } } -module.exports = Render; +export = Render; diff --git a/lib/hexo/router.js b/lib/hexo/router.ts similarity index 85% rename from lib/hexo/router.js rename to lib/hexo/router.ts index a1f3a32c8b..f00824d381 100644 --- a/lib/hexo/router.js +++ b/lib/hexo/router.ts @@ -1,12 +1,27 @@ -'use strict'; - -const { EventEmitter } = require('events'); -const Promise = require('bluebird'); -const Stream = require('stream'); +import { EventEmitter } from 'events'; +import Promise from 'bluebird'; +import Stream from 'stream'; const { Readable } = Stream; +interface Data { + data: any; + modified: boolean; +} + +declare module 'stream' { + export default class _Stream extends Stream { + readable: boolean; + } +} + class RouteStream extends Readable { - constructor(data) { + public _data: any; + public _ended: boolean; + public modified: any; + public push: any; + public emit: any; + + constructor(data: Data) { super({ objectMode: true }); this._data = data.data; @@ -71,7 +86,7 @@ class RouteStream extends Readable { } } -const _format = path => { +const _format = (path: string) => { path = path || ''; if (typeof path !== 'string') throw new TypeError('path must be a string!'); @@ -89,6 +104,11 @@ const _format = path => { }; class Router extends EventEmitter { + public routes: { + [key: string]: Data | null; + }; + public emit: any; + constructor() { super(); @@ -100,11 +120,11 @@ class Router extends EventEmitter { return Object.keys(routes).filter(key => routes[key]); } - format(path) { + format(path: string) { return _format(path); } - get(path) { + get(path: string) { if (typeof path !== 'string') throw new TypeError('path must be a string!'); const data = this.routes[this.format(path)]; @@ -124,7 +144,7 @@ class Router extends EventEmitter { if (typeof path !== 'string') throw new TypeError('path must be a string!'); if (data == null) throw new TypeError('data is required!'); - let obj; + let obj: Data; if (typeof data === 'object' && data.data != null) { obj = data; @@ -166,4 +186,4 @@ class Router extends EventEmitter { } } -module.exports = Router; +export = Router; diff --git a/lib/hexo/scaffold.js b/lib/hexo/scaffold.ts similarity index 87% rename from lib/hexo/scaffold.js rename to lib/hexo/scaffold.ts index c1d59f2aa2..18a1a5ff41 100644 --- a/lib/hexo/scaffold.js +++ b/lib/hexo/scaffold.ts @@ -1,9 +1,11 @@ -'use strict'; - -const { extname, join } = require('path'); -const { exists, listDir, readFile, unlink, writeFile } = require('hexo-fs'); +import { extname, join } from 'path'; +import { exists, listDir, readFile, unlink, writeFile } from 'hexo-fs'; class Scaffold { + public context: any; + public scaffoldDir: any; + public defaults: any; + constructor(context) { this.context = context; this.scaffoldDir = context.scaffold_dir; @@ -68,4 +70,4 @@ class Scaffold { } } -module.exports = Scaffold; +export = Scaffold; diff --git a/lib/hexo/source.js b/lib/hexo/source.ts similarity index 66% rename from lib/hexo/source.js rename to lib/hexo/source.ts index 00830b348f..ab4d26bc45 100644 --- a/lib/hexo/source.js +++ b/lib/hexo/source.ts @@ -1,6 +1,4 @@ -'use strict'; - -const Box = require('../box'); +import Box from '../box'; class Source extends Box { constructor(ctx) { @@ -10,4 +8,4 @@ class Source extends Box { } } -module.exports = Source; +export = Source; diff --git a/lib/hexo/update_package.js b/lib/hexo/update_package.ts similarity index 58% rename from lib/hexo/update_package.js rename to lib/hexo/update_package.ts index b0c16fa5ef..03319913e6 100644 --- a/lib/hexo/update_package.js +++ b/lib/hexo/update_package.ts @@ -1,9 +1,7 @@ -'use strict'; +import { join } from 'path'; +import { writeFile, exists, readFile } from 'hexo-fs'; -const { join } = require('path'); -const fs = require('hexo-fs'); - -module.exports = ctx => { +export = ctx => { const pkgPath = join(ctx.base_dir, 'package.json'); return readPkg(pkgPath).then(pkg => { @@ -16,16 +14,16 @@ module.exports = ctx => { pkg.hexo.version = ctx.version; ctx.log.debug('Updating package.json'); - return fs.writeFile(pkgPath, JSON.stringify(pkg, null, ' ')); + return writeFile(pkgPath, JSON.stringify(pkg, null, ' ')); }); }; function readPkg(path) { - return fs.exists(path).then(exist => { + return exists(path).then(exist => { if (!exist) return; - return fs.readFile(path).then(content => { - const pkg = JSON.parse(content); + return readFile(path).then(content => { + const pkg = JSON.parse(content as string); if (typeof pkg.hexo !== 'object') return; return pkg; diff --git a/lib/hexo/validate_config.js b/lib/hexo/validate_config.ts similarity index 94% rename from lib/hexo/validate_config.js rename to lib/hexo/validate_config.ts index 347feea886..8dfcb389e9 100644 --- a/lib/hexo/validate_config.js +++ b/lib/hexo/validate_config.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { config, log } = ctx; log.info('Validating config'); diff --git a/lib/models/asset.js b/lib/models/asset.ts similarity index 65% rename from lib/models/asset.js rename to lib/models/asset.ts index d821ead83f..006391d3b5 100644 --- a/lib/models/asset.js +++ b/lib/models/asset.ts @@ -1,10 +1,8 @@ -'use strict'; +import warehouse from 'warehouse'; +import { join } from 'path'; -const { Schema } = require('warehouse').default; -const { join } = require('path'); - -module.exports = ctx => { - const Asset = new Schema({ +export = ctx => { + const Asset = new warehouse.Schema({ _id: {type: String, required: true}, path: {type: String, required: true}, modified: {type: Boolean, default: true}, diff --git a/lib/models/cache.js b/lib/models/cache.ts similarity index 90% rename from lib/models/cache.js rename to lib/models/cache.ts index 89ef7286a5..d4b43f4722 100644 --- a/lib/models/cache.js +++ b/lib/models/cache.ts @@ -1,10 +1,8 @@ -'use strict'; +import warehouse from 'warehouse'; +import Promise from 'bluebird'; -const { Schema } = require('warehouse').default; -const Promise = require('bluebird'); - -module.exports = ctx => { - const Cache = new Schema({ +export = ctx => { + const Cache = new warehouse.Schema({ _id: {type: String, required: true}, hash: {type: String, default: ''}, modified: {type: Number, default: Date.now() } // UnixTime diff --git a/lib/models/category.js b/lib/models/category.ts similarity index 88% rename from lib/models/category.js rename to lib/models/category.ts index 5c535799a6..740bc67015 100644 --- a/lib/models/category.js +++ b/lib/models/category.ts @@ -1,12 +1,10 @@ -'use strict'; +import warehouse from 'warehouse'; +import { slugize, full_url_for } from 'hexo-util'; -const { Schema } = require('warehouse').default; -const { slugize, full_url_for } = require('hexo-util'); - -module.exports = ctx => { - const Category = new Schema({ +export = ctx => { + const Category = new warehouse.Schema({ name: {type: String, required: true}, - parent: {type: Schema.Types.CUID, ref: 'Category'} + parent: { type: warehouse.Schema.Types.CUID, ref: 'Category'} }); Category.virtual('slug').get(function() { diff --git a/lib/models/data.js b/lib/models/data.js deleted file mode 100644 index 3b3f25487f..0000000000 --- a/lib/models/data.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -const { Schema } = require('warehouse').default; - -module.exports = ctx => { - const Data = new Schema({ - _id: {type: String, required: true}, - data: Object - }); - - return Data; -}; diff --git a/lib/models/data.ts b/lib/models/data.ts new file mode 100644 index 0000000000..0cdefe318a --- /dev/null +++ b/lib/models/data.ts @@ -0,0 +1,10 @@ +import warehouse from 'warehouse'; + +export = ctx => { + const Data = new warehouse.Schema({ + _id: {type: String, required: true}, + data: Object + }); + + return Data; +}; diff --git a/lib/models/index.js b/lib/models/index.js deleted file mode 100644 index 18ae185867..0000000000 --- a/lib/models/index.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -const Asset = require('./asset'); -const Cache = require('./cache'); -const Category = require('./category'); -const Data = require('./data'); -const Page = require('./page'); -const Post = require('./post'); -const PostAsset = require('./post_asset'); -const PostCategory = require('./post_category'); -const PostTag = require('./post_tag'); -const Tag = require('./tag'); - -module.exports = { - Asset, Cache, Category, Data, Page, Post, PostAsset, PostCategory, PostTag, Tag -}; diff --git a/lib/models/index.ts b/lib/models/index.ts new file mode 100644 index 0000000000..d76aff60a9 --- /dev/null +++ b/lib/models/index.ts @@ -0,0 +1,10 @@ +export { default as Asset } from './asset'; +export { default as Cache } from './cache'; +export { default as Category } from './category'; +export { default as Data } from './data'; +export { default as Page } from './page'; +export { default as Post } from './post'; +export { default as PostAsset } from './post_asset'; +export { default as PostCategory } from './post_category'; +export { default as PostTag } from './post_tag'; +export { default as Tag } from './tag'; diff --git a/lib/models/page.js b/lib/models/page.ts similarity index 75% rename from lib/models/page.js rename to lib/models/page.ts index 0216ffede5..bbaa606422 100644 --- a/lib/models/page.js +++ b/lib/models/page.ts @@ -1,13 +1,11 @@ -'use strict'; +import warehouse from 'warehouse'; +import { join } from 'path'; +import Moment from './types/moment'; +import moment from 'moment'; +import { full_url_for } from 'hexo-util'; -const { Schema } = require('warehouse').default; -const { join } = require('path'); -const Moment = require('./types/moment'); -const moment = require('moment'); -const { full_url_for } = require('hexo-util'); - -module.exports = ctx => { - const Page = new Schema({ +export = ctx => { + const Page = new warehouse.Schema({ title: {type: String, default: ''}, date: { type: Moment, diff --git a/lib/models/post.js b/lib/models/post.ts similarity index 93% rename from lib/models/post.js rename to lib/models/post.ts index 4cb28421e3..60695323ec 100644 --- a/lib/models/post.js +++ b/lib/models/post.ts @@ -1,11 +1,9 @@ -'use strict'; - -const { Schema } = require('warehouse').default; -const moment = require('moment'); -const { extname, join, sep } = require('path'); -const Promise = require('bluebird'); -const Moment = require('./types/moment'); -const { full_url_for } = require('hexo-util'); +import warehouse from 'warehouse'; +import moment from 'moment'; +import { extname, join, sep } from 'path'; +import Promise from 'bluebird'; +import Moment from './types/moment'; +import { full_url_for } from 'hexo-util'; function pickID(data) { return data._id; @@ -15,8 +13,8 @@ function removeEmptyTag(tags) { return tags.filter(tag => tag != null && tag !== '').map(tag => `${tag}`); } -module.exports = ctx => { - const Post = new Schema({ +export = ctx => { + const Post = new warehouse.Schema({ id: String, title: {type: String, default: ''}, date: { @@ -128,7 +126,7 @@ module.exports = ctx => { return Category.find({_id: {$in: ids}}); }); - Post.method('setCategories', function(cats) { + Post.method('setCategories', function(cats: string[]) { if (this.notPublished()) { cats = []; } @@ -147,7 +145,7 @@ module.exports = ctx => { const hasHierarchy = cats.filter(Array.isArray).length > 0; // Add a hierarchy of categories - const addHierarchy = catHierarchy => { + const addHierarchy = (catHierarchy: string | string[]) => { const parentIds = []; if (!Array.isArray(catHierarchy)) catHierarchy = [catHierarchy]; // Don't use "Promise.map". It doesn't run in series. @@ -166,7 +164,7 @@ module.exports = ctx => { } // Insert the category if not exist - const obj = {name: cat}; + const obj: {name: string, parent?: string} = {name: cat}; if (i) obj.parent = parentIds[i - 1]; return Category.insert(obj).catch(err => { diff --git a/lib/models/post_asset.js b/lib/models/post_asset.ts similarity index 76% rename from lib/models/post_asset.js rename to lib/models/post_asset.ts index 9c3c3778f8..72ec5f90f1 100644 --- a/lib/models/post_asset.js +++ b/lib/models/post_asset.ts @@ -1,14 +1,12 @@ -'use strict'; +import warehouse from 'warehouse'; +import { join } from 'path'; -const { Schema } = require('warehouse').default; -const { join } = require('path'); - -module.exports = ctx => { - const PostAsset = new Schema({ +export = ctx => { + const PostAsset = new warehouse.Schema({ _id: {type: String, required: true}, slug: {type: String, required: true}, modified: {type: Boolean, default: true}, - post: {type: Schema.Types.CUID, ref: 'Post'}, + post: {type: warehouse.Schema.Types.CUID, ref: 'Post'}, renderable: {type: Boolean, default: true} }); diff --git a/lib/models/post_category.js b/lib/models/post_category.js deleted file mode 100644 index f7169d0f0d..0000000000 --- a/lib/models/post_category.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -const { Schema } = require('warehouse').default; - -module.exports = ctx => { - const PostCategory = new Schema({ - post_id: {type: Schema.Types.CUID, ref: 'Post'}, - category_id: {type: Schema.Types.CUID, ref: 'Category'} - }); - - return PostCategory; -}; diff --git a/lib/models/post_category.ts b/lib/models/post_category.ts new file mode 100644 index 0000000000..f3c813f8be --- /dev/null +++ b/lib/models/post_category.ts @@ -0,0 +1,10 @@ +import warehouse from 'warehouse'; + +export = ctx => { + const PostCategory = new warehouse.Schema({ + post_id: {type: warehouse.Schema.Types.CUID, ref: 'Post'}, + category_id: {type: warehouse.Schema.Types.CUID, ref: 'Category'} + }); + + return PostCategory; +}; diff --git a/lib/models/post_tag.js b/lib/models/post_tag.js deleted file mode 100644 index 21ce51f287..0000000000 --- a/lib/models/post_tag.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -const { Schema } = require('warehouse').default; - -module.exports = ctx => { - const PostTag = new Schema({ - post_id: {type: Schema.Types.CUID, ref: 'Post'}, - tag_id: {type: Schema.Types.CUID, ref: 'Tag'} - }); - - return PostTag; -}; diff --git a/lib/models/post_tag.ts b/lib/models/post_tag.ts new file mode 100644 index 0000000000..e727ca5e3e --- /dev/null +++ b/lib/models/post_tag.ts @@ -0,0 +1,10 @@ +import warehouse from 'warehouse'; + +export = ctx => { + const PostTag = new warehouse.Schema({ + post_id: {type: warehouse.Schema.Types.CUID, ref: 'Post'}, + tag_id: {type: warehouse.Schema.Types.CUID, ref: 'Tag'} + }); + + return PostTag; +}; diff --git a/lib/models/tag.js b/lib/models/tag.ts similarity index 90% rename from lib/models/tag.js rename to lib/models/tag.ts index 7f6245c861..9c5b10a55e 100644 --- a/lib/models/tag.js +++ b/lib/models/tag.ts @@ -1,11 +1,9 @@ -'use strict'; - -const { Schema } = require('warehouse').default; -const { slugize, full_url_for } = require('hexo-util'); +import warehouse from 'warehouse'; +import { slugize, full_url_for } from 'hexo-util'; const { hasOwnProperty: hasOwn } = Object.prototype; -module.exports = ctx => { - const Tag = new Schema({ +export = ctx => { + const Tag = new warehouse.Schema({ name: {type: String, required: true} }); diff --git a/lib/models/types/moment.js b/lib/models/types/moment.ts similarity index 82% rename from lib/models/types/moment.js rename to lib/models/types/moment.ts index 95dca78b65..59a86e1479 100644 --- a/lib/models/types/moment.js +++ b/lib/models/types/moment.ts @@ -1,9 +1,16 @@ -'use strict'; +import warehouse from 'warehouse'; +import { moment, toMomentLocale } from '../../plugins/helper/date'; -const { SchemaType } = require('warehouse').default; -const { moment, toMomentLocale } = require('../../plugins/helper/date'); +declare module 'moment' { + export default interface Moment extends moment.Moment { + _d: Date; + // eslint-disable-next-line semi + } +} + +class SchemaTypeMoment extends warehouse.SchemaType { + public options: any; -class SchemaTypeMoment extends SchemaType { constructor(name, options = {}) { super(name, options); } @@ -48,7 +55,7 @@ class SchemaTypeMoment extends SchemaType { return 0; } - parse(value, data) { + parse(value) { if (value) return toMoment(value); } @@ -87,4 +94,4 @@ function toMoment(value) { return moment(value); } -module.exports = SchemaTypeMoment; +export = SchemaTypeMoment; diff --git a/lib/plugins/console/clean.js b/lib/plugins/console/clean.ts similarity index 62% rename from lib/plugins/console/clean.js rename to lib/plugins/console/clean.ts index ab6895f165..fb799039d8 100644 --- a/lib/plugins/console/clean.js +++ b/lib/plugins/console/clean.ts @@ -1,7 +1,5 @@ -'use strict'; - -const Promise = require('bluebird'); -const fs = require('hexo-fs'); +import Promise from 'bluebird'; +import { exists, unlink, rmdir } from 'hexo-fs'; function cleanConsole(args) { return Promise.all([ @@ -14,10 +12,10 @@ function cleanConsole(args) { function deleteDatabase(ctx) { const dbPath = ctx.database.options.path; - return fs.exists(dbPath).then(exist => { + return exists(dbPath).then(exist => { if (!exist) return; - return fs.unlink(dbPath).then(() => { + return unlink(dbPath).then(() => { ctx.log.info('Deleted database.'); }); }); @@ -26,13 +24,13 @@ function deleteDatabase(ctx) { function deletePublicDir(ctx) { const publicDir = ctx.public_dir; - return fs.exists(publicDir).then(exist => { + return exists(publicDir).then(exist => { if (!exist) return; - return fs.rmdir(publicDir).then(() => { + return rmdir(publicDir).then(() => { ctx.log.info('Deleted public folder.'); }); }); } -module.exports = cleanConsole; +export = cleanConsole; diff --git a/lib/plugins/console/config.js b/lib/plugins/console/config.ts similarity index 83% rename from lib/plugins/console/config.js rename to lib/plugins/console/config.ts index 3811746475..841c241c23 100644 --- a/lib/plugins/console/config.js +++ b/lib/plugins/console/config.ts @@ -1,9 +1,7 @@ -'use strict'; - -const yaml = require('js-yaml'); -const fs = require('hexo-fs'); -const { extname } = require('path'); -const Promise = require('bluebird'); +import yaml from 'js-yaml'; +import { exists, writeFile } from 'hexo-fs'; +import { extname } from 'path'; +import Promise from 'bluebird'; function configConsole(args) { const key = args._[0]; @@ -23,7 +21,7 @@ function configConsole(args) { const configPath = this.config_path; const ext = extname(configPath); - return fs.exists(configPath).then(exist => { + return exists(configPath).then(exist => { if (!exist) return {}; return this.render.render({path: configPath}); }).then(config => { @@ -33,7 +31,7 @@ function configConsole(args) { const result = ext === '.json' ? JSON.stringify(config) : yaml.dump(config); - return fs.writeFile(configPath, result); + return writeFile(configPath, result); }); } @@ -83,4 +81,4 @@ function castValue(value) { return value; } -module.exports = configConsole; +export = configConsole; diff --git a/lib/plugins/console/deploy.js b/lib/plugins/console/deploy.ts similarity index 83% rename from lib/plugins/console/deploy.js rename to lib/plugins/console/deploy.ts index bd35db8a23..6da32c2e76 100644 --- a/lib/plugins/console/deploy.js +++ b/lib/plugins/console/deploy.ts @@ -1,7 +1,5 @@ -'use strict'; - -const { exists } = require('hexo-fs'); -const { underline, magenta } = require('picocolors'); +import { exists } from 'hexo-fs'; +import { underline, magenta } from 'picocolors'; function deployConsole(args) { let config = this.config.deploy; @@ -50,7 +48,8 @@ function deployConsole(args) { this.log.info('Deploying: %s', magenta(type)); - return Reflect.apply(deployers[type], this, [{ ...item, ...args }]).then(() => { + // eslint-disable-next-line no-extra-parens + return (Reflect.apply(deployers[type], this, [{ ...item, ...args }]) as any).then(() => { this.log.info('Deploy done: %s', magenta(type)); }); }).then(() => { @@ -58,4 +57,4 @@ function deployConsole(args) { }); } -module.exports = deployConsole; +export = deployConsole; diff --git a/lib/plugins/console/generate.js b/lib/plugins/console/generate.ts similarity index 89% rename from lib/plugins/console/generate.js rename to lib/plugins/console/generate.ts index 261ba40132..ccae2b3d94 100644 --- a/lib/plugins/console/generate.js +++ b/lib/plugins/console/generate.ts @@ -1,15 +1,25 @@ -'use strict'; - -const { exists, writeFile, unlink, stat, mkdirs } = require('hexo-fs'); -const { join } = require('path'); -const Promise = require('bluebird'); -const prettyHrtime = require('pretty-hrtime'); -const { cyan, magenta } = require('picocolors'); -const tildify = require('tildify'); -const { PassThrough } = require('stream'); -const { createSha1Hash } = require('hexo-util'); +import { exists, writeFile, unlink, stat, mkdirs } from 'hexo-fs'; +import { join } from 'path'; +import Promise from 'bluebird'; +import prettyHrtime from 'pretty-hrtime'; +import { cyan, magenta } from 'picocolors'; +import tildify from 'tildify'; +import { PassThrough } from 'stream'; +import { createSha1Hash } from 'hexo-util'; class Generater { + public context: any; + public force: any; + public bail: any; + public concurrency: any; + public watch: any; + public deploy: any; + public generatingFiles: any; + public start: any; + public args: any; + public route: any; + public log: any; + constructor(ctx, args) { this.context = ctx; this.force = args.f || args.force; @@ -48,7 +58,7 @@ class Generater { generatingFiles.delete(path); }); } - writeFile(path, force) { + writeFile(path, force?) { const { route, log } = this.context; const publicDir = this.context.public_dir; const Cache = this.context.model('Cache'); @@ -196,4 +206,4 @@ function generateConsole(args = {}) { }); } -module.exports = generateConsole; +export = generateConsole; diff --git a/lib/plugins/console/index.js b/lib/plugins/console/index.ts similarity index 98% rename from lib/plugins/console/index.js rename to lib/plugins/console/index.ts index 3a34b7b0fb..829f8f0baf 100644 --- a/lib/plugins/console/index.js +++ b/lib/plugins/console/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = function(ctx) { +export = function(ctx) { const { console } = ctx.extend; console.register('clean', 'Remove generated files and cache.', require('./clean')); @@ -77,4 +75,4 @@ module.exports = function(ctx) { {name: '--pretty', desc: 'Prettify JSON output'} ] }, require('./render')); -}; +} diff --git a/lib/plugins/console/list/category.js b/lib/plugins/console/list/category.ts similarity index 70% rename from lib/plugins/console/list/category.js rename to lib/plugins/console/list/category.ts index 8550ec6c1d..0044ec3a0e 100644 --- a/lib/plugins/console/list/category.js +++ b/lib/plugins/console/list/category.ts @@ -1,8 +1,6 @@ -'use strict'; - -const { underline } = require('picocolors'); -const table = require('text-table'); -const { stringLength } = require('./common'); +import { underline } from 'picocolors'; +import table from 'text-table'; +import { stringLength } from './common'; function listCategory() { const categories = this.model('Category'); @@ -23,4 +21,4 @@ function listCategory() { if (data.length === 1) console.log('No categories.'); } -module.exports = listCategory; +export = listCategory; diff --git a/lib/plugins/console/list/common.js b/lib/plugins/console/list/common.ts similarity index 71% rename from lib/plugins/console/list/common.js rename to lib/plugins/console/list/common.ts index ee0b12d039..5adcb8022c 100644 --- a/lib/plugins/console/list/common.js +++ b/lib/plugins/console/list/common.ts @@ -1,8 +1,6 @@ -'use strict'; +import strip from 'strip-ansi'; -const strip = require('strip-ansi'); - -exports.stringLength = str => { +export function stringLength(str) { str = strip(str); const len = str.length; @@ -16,4 +14,4 @@ exports.stringLength = str => { } return result; -}; +} diff --git a/lib/plugins/console/list/index.js b/lib/plugins/console/list/index.ts similarity index 61% rename from lib/plugins/console/list/index.js rename to lib/plugins/console/list/index.ts index debab88983..7c3f084138 100644 --- a/lib/plugins/console/list/index.js +++ b/lib/plugins/console/list/index.ts @@ -1,11 +1,9 @@ -'use strict'; - -const abbrev = require('abbrev'); -const page = require('./page'); -const post = require('./post'); -const route = require('./route'); -const tag = require('./tag'); -const category = require('./category'); +import abbrev from 'abbrev'; +import page from './page'; +import post from './post'; +import route from './route'; +import tag from './tag'; +import category from './category'; const store = { page, post, route, tag, category @@ -24,4 +22,4 @@ function listConsole(args) { return this.load().then(() => Reflect.apply(store[alias[type]], this, [args])); } -module.exports = listConsole; +export = listConsole; diff --git a/lib/plugins/console/list/page.js b/lib/plugins/console/list/page.ts similarity index 71% rename from lib/plugins/console/list/page.js rename to lib/plugins/console/list/page.ts index 7ea880ed54..d132231450 100644 --- a/lib/plugins/console/list/page.js +++ b/lib/plugins/console/list/page.ts @@ -1,8 +1,6 @@ -'use strict'; - -const { magenta, underline, gray } = require('picocolors'); -const table = require('text-table'); -const { stringLength } = require('./common'); +import { magenta, underline, gray } from 'picocolors'; +import table from 'text-table'; +import { stringLength } from './common'; function listPage() { const Page = this.model('Page'); @@ -25,4 +23,4 @@ function listPage() { if (data.length === 1) console.log('No pages.'); } -module.exports = listPage; +export = listPage; diff --git a/lib/plugins/console/list/post.js b/lib/plugins/console/list/post.ts similarity index 80% rename from lib/plugins/console/list/post.js rename to lib/plugins/console/list/post.ts index e09a975b5e..e4dca1a578 100644 --- a/lib/plugins/console/list/post.js +++ b/lib/plugins/console/list/post.ts @@ -1,8 +1,6 @@ -'use strict'; - -const { gray, magenta, underline } = require('picocolors'); -const table = require('text-table'); -const { stringLength } = require('./common'); +import { gray, magenta, underline } from 'picocolors'; +import table from 'text-table'; +import { stringLength } from './common'; function mapName(item) { return item.name; @@ -38,4 +36,4 @@ function listPost() { if (data.length === 1) console.log('No posts.'); } -module.exports = listPost; +export = listPost; diff --git a/lib/plugins/console/list/route.js b/lib/plugins/console/list/route.ts similarity index 92% rename from lib/plugins/console/list/route.js rename to lib/plugins/console/list/route.ts index d6a3cdbb8e..a29e4e4c54 100644 --- a/lib/plugins/console/list/route.js +++ b/lib/plugins/console/list/route.ts @@ -1,6 +1,4 @@ -'use strict'; - -const archy = require('archy'); +import archy from 'archy'; function listRoute() { const routes = this.route.list().sort(); @@ -50,4 +48,4 @@ function buildNodes(tree) { return nodes; } -module.exports = listRoute; +export = listRoute; diff --git a/lib/plugins/console/list/tag.js b/lib/plugins/console/list/tag.ts similarity index 70% rename from lib/plugins/console/list/tag.js rename to lib/plugins/console/list/tag.ts index 6f5dab7c69..09c0a148df 100644 --- a/lib/plugins/console/list/tag.js +++ b/lib/plugins/console/list/tag.ts @@ -1,8 +1,6 @@ -'use strict'; - -const { magenta, underline } = require('picocolors'); -const table = require('text-table'); -const { stringLength } = require('./common'); +import { magenta, underline } from 'picocolors'; +import table from 'text-table'; +import { stringLength } from './common'; function listTag() { const Tag = this.model('Tag'); @@ -23,4 +21,4 @@ function listTag() { if (data.length === 1) console.log('No tags.'); } -module.exports = listTag; +export = listTag; diff --git a/lib/plugins/console/migrate.js b/lib/plugins/console/migrate.ts similarity index 86% rename from lib/plugins/console/migrate.js rename to lib/plugins/console/migrate.ts index 707b14ba55..df341f6ed4 100644 --- a/lib/plugins/console/migrate.js +++ b/lib/plugins/console/migrate.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { underline, magenta } = require('picocolors'); +import { underline, magenta } from 'picocolors'; function migrateConsole(args) { // Display help message if user didn't input any arguments @@ -26,4 +24,4 @@ function migrateConsole(args) { return Reflect.apply(migrators[type], this, [args]); } -module.exports = migrateConsole; +export = migrateConsole; diff --git a/lib/plugins/console/new.js b/lib/plugins/console/new.ts similarity index 86% rename from lib/plugins/console/new.js rename to lib/plugins/console/new.ts index a73663e27f..becbe1c625 100644 --- a/lib/plugins/console/new.js +++ b/lib/plugins/console/new.ts @@ -1,8 +1,6 @@ -'use strict'; - -const tildify = require('tildify'); -const { magenta } = require('picocolors'); -const { basename } = require('path'); +import tildify from 'tildify'; +import { magenta } from 'picocolors'; +import { basename } from 'path'; const reservedKeys = { _: true, @@ -53,4 +51,4 @@ function newConsole(args) { }); } -module.exports = newConsole; +export = newConsole; diff --git a/lib/plugins/console/publish.js b/lib/plugins/console/publish.ts similarity index 76% rename from lib/plugins/console/publish.js rename to lib/plugins/console/publish.ts index 2192e196a1..f73d87ec55 100644 --- a/lib/plugins/console/publish.js +++ b/lib/plugins/console/publish.ts @@ -1,7 +1,5 @@ -'use strict'; - -const tildify = require('tildify'); -const { magenta } = require('picocolors'); +import tildify from 'tildify'; +import { magenta } from 'picocolors'; function publishConsole(args) { // Display help message if user didn't input any arguments @@ -17,4 +15,4 @@ function publishConsole(args) { }); } -module.exports = publishConsole; +export = publishConsole; diff --git a/lib/plugins/console/render.js b/lib/plugins/console/render.ts similarity index 75% rename from lib/plugins/console/render.js rename to lib/plugins/console/render.ts index 57028ba0d1..01cb57c581 100644 --- a/lib/plugins/console/render.js +++ b/lib/plugins/console/render.ts @@ -1,10 +1,8 @@ -'use strict'; - -const { resolve } = require('path'); -const tildify = require('tildify'); -const prettyHrtime = require('pretty-hrtime'); -const fs = require('hexo-fs'); -const { cyan, magenta } = require('picocolors'); +import { resolve } from 'path'; +import tildify from 'tildify'; +import prettyHrtime from 'pretty-hrtime'; +import { writeFile } from 'hexo-fs'; +import { cyan, magenta } from 'picocolors'; function renderConsole(args) { // Display help message if user didn't input any arguments @@ -36,8 +34,8 @@ function renderConsole(args) { const interval = prettyHrtime(process.hrtime(start)); log.info('Rendered in %s: %s -> %s', cyan(interval), magenta(tildify(src)), magenta(tildify(dest))); - return fs.writeFile(dest, result); + return writeFile(dest, result); }); } -module.exports = renderConsole; +export = renderConsole; diff --git a/lib/plugins/filter/after_post_render/excerpt.js b/lib/plugins/filter/after_post_render/excerpt.ts similarity index 91% rename from lib/plugins/filter/after_post_render/excerpt.js rename to lib/plugins/filter/after_post_render/excerpt.ts index d5705c09be..ef1746a352 100644 --- a/lib/plugins/filter/after_post_render/excerpt.js +++ b/lib/plugins/filter/after_post_render/excerpt.ts @@ -1,5 +1,3 @@ -'use strict'; - const rExcerpt = //i; function excerptFilter(data) { @@ -20,4 +18,4 @@ function excerptFilter(data) { } } -module.exports = excerptFilter; +export = excerptFilter; diff --git a/lib/plugins/filter/after_post_render/external_link.js b/lib/plugins/filter/after_post_render/external_link.ts similarity index 90% rename from lib/plugins/filter/after_post_render/external_link.js rename to lib/plugins/filter/after_post_render/external_link.ts index cd7bec136c..0b116de8b4 100644 --- a/lib/plugins/filter/after_post_render/external_link.js +++ b/lib/plugins/filter/after_post_render/external_link.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { isExternalLink } = require('hexo-util'); +import { isExternalLink } from 'hexo-util'; let EXTERNAL_LINK_POST_ENABLED = true; const rATag = /]+?\s+?)href=["']((?:https?:|\/\/)[^<>"']+)["'][^<>]*>/gi; const rTargetAttr = /target=/i; @@ -31,4 +29,4 @@ function externalLinkFilter(data) { }); } -module.exports = externalLinkFilter; +export = externalLinkFilter; diff --git a/lib/plugins/filter/after_post_render/index.js b/lib/plugins/filter/after_post_render/index.ts similarity index 80% rename from lib/plugins/filter/after_post_render/index.js rename to lib/plugins/filter/after_post_render/index.ts index fbc7a7822c..87bb8b433c 100644 --- a/lib/plugins/filter/after_post_render/index.js +++ b/lib/plugins/filter/after_post_render/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { filter } = ctx.extend; filter.register('after_post_render', require('./external_link')); diff --git a/lib/plugins/filter/after_render/external_link.js b/lib/plugins/filter/after_render/external_link.ts similarity index 90% rename from lib/plugins/filter/after_render/external_link.js rename to lib/plugins/filter/after_render/external_link.ts index 40ff7b6b65..a5d7218133 100644 --- a/lib/plugins/filter/after_render/external_link.js +++ b/lib/plugins/filter/after_render/external_link.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { isExternalLink } = require('hexo-util'); +import { isExternalLink } from 'hexo-util'; let EXTERNAL_LINK_SITE_ENABLED = true; const rATag = /]+?\s+?)href=["']((?:https?:|\/\/)[^<>"']+)["'][^<>]*>/gi; @@ -32,4 +30,4 @@ function externalLinkFilter(data) { }); } -module.exports = externalLinkFilter; +export = externalLinkFilter; diff --git a/lib/plugins/filter/after_render/index.js b/lib/plugins/filter/after_render/index.ts similarity index 80% rename from lib/plugins/filter/after_render/index.js rename to lib/plugins/filter/after_render/index.ts index 819e0490ce..509e95a0f8 100644 --- a/lib/plugins/filter/after_render/index.js +++ b/lib/plugins/filter/after_render/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { filter } = ctx.extend; filter.register('after_render:html', require('./external_link')); diff --git a/lib/plugins/filter/after_render/meta_generator.js b/lib/plugins/filter/after_render/meta_generator.ts similarity index 88% rename from lib/plugins/filter/after_render/meta_generator.js rename to lib/plugins/filter/after_render/meta_generator.ts index d5e4f2c2f3..4c04daee3a 100644 --- a/lib/plugins/filter/after_render/meta_generator.js +++ b/lib/plugins/filter/after_render/meta_generator.ts @@ -1,5 +1,3 @@ -'use strict'; - let NEED_INJECT = true; let META_GENERATOR_TAG; @@ -17,4 +15,4 @@ function hexoMetaGeneratorInject(data) { return data.replace('', `${META_GENERATOR_TAG}`); } -module.exports = hexoMetaGeneratorInject; +export = hexoMetaGeneratorInject; diff --git a/lib/plugins/filter/before_exit/index.js b/lib/plugins/filter/before_exit/index.ts similarity index 70% rename from lib/plugins/filter/before_exit/index.js rename to lib/plugins/filter/before_exit/index.ts index 374eb8a225..ba3312749e 100644 --- a/lib/plugins/filter/before_exit/index.js +++ b/lib/plugins/filter/before_exit/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { filter } = ctx.extend; filter.register('before_exit', require('./save_database')); diff --git a/lib/plugins/filter/before_exit/save_database.js b/lib/plugins/filter/before_exit/save_database.ts similarity index 76% rename from lib/plugins/filter/before_exit/save_database.js rename to lib/plugins/filter/before_exit/save_database.ts index a5388e399e..9aadce2ee8 100644 --- a/lib/plugins/filter/before_exit/save_database.js +++ b/lib/plugins/filter/before_exit/save_database.ts @@ -1,5 +1,3 @@ -'use strict'; - function saveDatabaseFilter() { if (!this.env.init || !this._dbLoaded) return; @@ -8,4 +6,4 @@ function saveDatabaseFilter() { }); } -module.exports = saveDatabaseFilter; +export = saveDatabaseFilter; diff --git a/lib/plugins/filter/before_generate/index.js b/lib/plugins/filter/before_generate/index.ts similarity index 71% rename from lib/plugins/filter/before_generate/index.js rename to lib/plugins/filter/before_generate/index.ts index 960e469e3c..288bb1651a 100644 --- a/lib/plugins/filter/before_generate/index.js +++ b/lib/plugins/filter/before_generate/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { filter } = ctx.extend; filter.register('before_generate', require('./render_post')); diff --git a/lib/plugins/filter/before_generate/render_post.js b/lib/plugins/filter/before_generate/render_post.ts similarity index 75% rename from lib/plugins/filter/before_generate/render_post.js rename to lib/plugins/filter/before_generate/render_post.ts index 100450004a..ae202e9477 100644 --- a/lib/plugins/filter/before_generate/render_post.js +++ b/lib/plugins/filter/before_generate/render_post.ts @@ -1,12 +1,10 @@ -'use strict'; - -const Promise = require('bluebird'); +import Promise from 'bluebird'; function renderPostFilter(data) { const renderPosts = model => { const posts = model.toArray().filter(post => post.content == null); - return Promise.map(posts, post => { + return Promise.map(posts, (post: any) => { post.content = post._content; post.site = {data}; @@ -20,4 +18,4 @@ function renderPostFilter(data) { ]); } -module.exports = renderPostFilter; +export = renderPostFilter; diff --git a/lib/plugins/filter/before_post_render/backtick_code_block.js b/lib/plugins/filter/before_post_render/backtick_code_block.ts similarity index 93% rename from lib/plugins/filter/before_post_render/backtick_code_block.js rename to lib/plugins/filter/before_post_render/backtick_code_block.ts index 32f3590e27..b9df3e60f2 100644 --- a/lib/plugins/filter/before_post_render/backtick_code_block.js +++ b/lib/plugins/filter/before_post_render/backtick_code_block.ts @@ -1,12 +1,17 @@ -'use strict'; - const rBacktick = /^((?:[^\S\r\n]*>){0,3}[^\S\r\n]*)(`{3,}|~{3,})[^\S\r\n]*((?:.*?[^`\s])?)[^\S\r\n]*\n((?:[\s\S]*?\n)?)(?:(?:[^\S\r\n]*>){0,3}[^\S\r\n]*)\2[^\S\r\n]?(\n+|$)/gm; const rAllOptions = /([^\s]+)\s+(.+?)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/; const rLangCaption = /([^\s]+)\s*(.+)?/; const escapeSwigTag = str => str.replace(/{/g, '{').replace(/}/g, '}'); -module.exports = ctx => { +interface Options { + lang: string, + caption: string, + lines_length: number, + firstLineNumber?: string | number +} + +export = ctx => { return function backtickCodeBlock(data) { const dataContent = data.content; @@ -46,7 +51,7 @@ module.exports = ctx => { content = content.replace(regexp, ''); } - const options = { + const options: Options = { lang, caption, lines_length: content.split('\n').length diff --git a/lib/plugins/filter/before_post_render/index.js b/lib/plugins/filter/before_post_render/index.ts similarity index 81% rename from lib/plugins/filter/before_post_render/index.js rename to lib/plugins/filter/before_post_render/index.ts index bcff7246b4..07bde83da3 100644 --- a/lib/plugins/filter/before_post_render/index.js +++ b/lib/plugins/filter/before_post_render/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { filter } = ctx.extend; filter.register('before_post_render', require('./backtick_code_block')(ctx)); diff --git a/lib/plugins/filter/before_post_render/titlecase.js b/lib/plugins/filter/before_post_render/titlecase.ts similarity index 83% rename from lib/plugins/filter/before_post_render/titlecase.js rename to lib/plugins/filter/before_post_render/titlecase.ts index 0fad5bc4e9..24e596ace8 100644 --- a/lib/plugins/filter/before_post_render/titlecase.js +++ b/lib/plugins/filter/before_post_render/titlecase.ts @@ -1,5 +1,3 @@ -'use strict'; - let titlecase; function titlecaseFilter(data) { @@ -9,4 +7,4 @@ function titlecaseFilter(data) { data.title = titlecase(data.title); } -module.exports = titlecaseFilter; +export = titlecaseFilter; diff --git a/lib/plugins/filter/index.js b/lib/plugins/filter/index.ts similarity index 90% rename from lib/plugins/filter/index.js rename to lib/plugins/filter/index.ts index f349b99b29..612e116ece 100644 --- a/lib/plugins/filter/index.js +++ b/lib/plugins/filter/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { filter } = ctx.extend; require('./after_render')(ctx); diff --git a/lib/plugins/filter/new_post_path.js b/lib/plugins/filter/new_post_path.ts similarity index 81% rename from lib/plugins/filter/new_post_path.js rename to lib/plugins/filter/new_post_path.ts index 706c8a2037..c06b946230 100644 --- a/lib/plugins/filter/new_post_path.js +++ b/lib/plugins/filter/new_post_path.ts @@ -1,10 +1,8 @@ -'use strict'; - -const { join, extname } = require('path'); -const moment = require('moment'); -const Promise = require('bluebird'); -const { createSha1Hash, Permalink } = require('hexo-util'); -const fs = require('hexo-fs'); +import { join, extname } from 'path'; +import moment from 'moment'; +import Promise from 'bluebird'; +import { createSha1Hash, Permalink } from 'hexo-util'; +import { ensurePath } from 'hexo-fs'; let permalink; const reservedKeys = { @@ -17,7 +15,14 @@ const reservedKeys = { hash: true }; -function newPostPathFilter(data = {}, replace) { +interface Data { + path?: string; + layout?: string; + slug?: string; + date?: Date; +} + +function newPostPathFilter(data: Data = {}, replace) { const sourceDir = this.source_dir; const draftDir = join(sourceDir, '_drafts'); const postDir = join(sourceDir, '_posts'); @@ -27,7 +32,7 @@ function newPostPathFilter(data = {}, replace) { const { path, layout, slug } = data; if (!permalink || permalink.rule !== newPostName) { - permalink = new Permalink(newPostName); + permalink = new Permalink(newPostName, {}); } let target = ''; @@ -94,7 +99,7 @@ function newPostPathFilter(data = {}, replace) { return Promise.resolve(target); } - return fs.ensurePath(target); + return ensurePath(target); } -module.exports = newPostPathFilter; +export = newPostPathFilter; diff --git a/lib/plugins/filter/post_permalink.js b/lib/plugins/filter/post_permalink.ts similarity index 85% rename from lib/plugins/filter/post_permalink.js rename to lib/plugins/filter/post_permalink.ts index 1087c5ef37..c715e67b5d 100644 --- a/lib/plugins/filter/post_permalink.js +++ b/lib/plugins/filter/post_permalink.ts @@ -1,7 +1,5 @@ -'use strict'; - -const { createSha1Hash, Permalink, slugize } = require('hexo-util'); -const { basename } = require('path'); +import { createSha1Hash, Permalink, slugize } from 'hexo-util'; +import { basename } from 'path'; let permalink; function postPermalinkFilter(data) { @@ -29,19 +27,18 @@ function postPermalinkFilter(data) { second: date.format('ss'), i_month: date.format('M'), i_day: date.format('D'), - hash + hash, + category: config.default_category }; if (!permalink || permalink.rule !== config.permalink) { - permalink = new Permalink(config.permalink); + permalink = new Permalink(config.permalink, {}); } const { categories } = data; if (categories.length) { meta.category = categories.last().slug; - } else { - meta.category = config.default_category; } const keys = Object.keys(data); @@ -67,4 +64,4 @@ function postPermalinkFilter(data) { return permalink.stringify(meta); } -module.exports = postPermalinkFilter; +export = postPermalinkFilter; diff --git a/lib/plugins/filter/template_locals/i18n.js b/lib/plugins/filter/template_locals/i18n.ts similarity index 90% rename from lib/plugins/filter/template_locals/i18n.js rename to lib/plugins/filter/template_locals/i18n.ts index 9bdddb1fb6..73367d8df0 100644 --- a/lib/plugins/filter/template_locals/i18n.js +++ b/lib/plugins/filter/template_locals/i18n.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { Pattern } = require('hexo-util'); +import { Pattern } from 'hexo-util'; function i18nLocalsFilter(locals) { const { i18n } = this.theme; @@ -33,4 +31,4 @@ function i18nLocalsFilter(locals) { locals._p = i18n._p(languages); } -module.exports = i18nLocalsFilter; +export = i18nLocalsFilter; diff --git a/lib/plugins/filter/template_locals/index.js b/lib/plugins/filter/template_locals/index.ts similarity index 69% rename from lib/plugins/filter/template_locals/index.js rename to lib/plugins/filter/template_locals/index.ts index 53ce0da6d3..663cb8ab3f 100644 --- a/lib/plugins/filter/template_locals/index.js +++ b/lib/plugins/filter/template_locals/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { filter } = ctx.extend; filter.register('template_locals', require('./i18n')); diff --git a/lib/plugins/generator/asset.js b/lib/plugins/generator/asset.ts similarity index 53% rename from lib/plugins/generator/asset.js rename to lib/plugins/generator/asset.ts index 3fda4db77d..b7dcb47a83 100644 --- a/lib/plugins/generator/asset.js +++ b/lib/plugins/generator/asset.ts @@ -1,20 +1,31 @@ -'use strict'; - -const fs = require('hexo-fs'); -const Promise = require('bluebird'); -const { extname } = require('path'); -const { magenta } = require('picocolors'); +/* eslint-disable @typescript-eslint/ban-ts-comment */ +import { exists, createReadStream } from 'hexo-fs'; +import Promise from 'bluebird'; +import { extname } from 'path'; +import { magenta } from 'picocolors'; +import warehouse from 'warehouse'; + +interface Data { + modified: boolean; + data?: () => any; +} const process = (name, ctx) => { - return Promise.filter(ctx.model(name).toArray(), asset => fs.exists(asset.source).tap(exist => { + // @ts-expect-error + return Promise.filter(ctx.model(name).toArray(), (asset: warehouse['Schema']) => exists(asset.source).tap(exist => { + // @ts-expect-error if (!exist) return asset.remove(); - })).map(asset => { + })).map((asset: warehouse['Schema']) => { + // @ts-expect-error const { source } = asset; + // @ts-expect-error let { path } = asset; - const data = { + const data: Data = { + // @ts-expect-error modified: asset.modified }; + // @ts-expect-error if (asset.renderable && ctx.render.isRenderable(path)) { // Replace extension name if the asset is renderable const filename = path.substring(0, path.length - extname(path).length); @@ -28,7 +39,7 @@ const process = (name, ctx) => { ctx.log.error({err}, 'Asset render failed: %s', magenta(path)); }); } else { - data.data = () => fs.createReadStream(source); + data.data = () => createReadStream(source); } return { path, data }; @@ -42,4 +53,4 @@ function assetGenerator() { ]).then(data => [].concat(...data)); } -module.exports = assetGenerator; +export = assetGenerator; diff --git a/lib/plugins/generator/index.js b/lib/plugins/generator/index.ts similarity index 82% rename from lib/plugins/generator/index.js rename to lib/plugins/generator/index.ts index da39f2680f..a07031c380 100644 --- a/lib/plugins/generator/index.js +++ b/lib/plugins/generator/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { generator } = ctx.extend; generator.register('asset', require('./asset')); diff --git a/lib/plugins/generator/page.js b/lib/plugins/generator/page.ts similarity index 90% rename from lib/plugins/generator/page.js rename to lib/plugins/generator/page.ts index a80d42254c..8dbbcd817c 100644 --- a/lib/plugins/generator/page.js +++ b/lib/plugins/generator/page.ts @@ -1,5 +1,3 @@ -'use strict'; - function pageGenerator(locals) { return locals.pages.map(page => { const { path, layout } = page; @@ -24,4 +22,4 @@ function pageGenerator(locals) { }); } -module.exports = pageGenerator; +export = pageGenerator; diff --git a/lib/plugins/generator/post.js b/lib/plugins/generator/post.ts similarity index 92% rename from lib/plugins/generator/post.js rename to lib/plugins/generator/post.ts index 0d32332329..4deec563dd 100644 --- a/lib/plugins/generator/post.js +++ b/lib/plugins/generator/post.ts @@ -1,5 +1,3 @@ -'use strict'; - function postGenerator(locals) { const posts = locals.posts.sort('-date').toArray(); const { length } = posts; @@ -30,4 +28,4 @@ function postGenerator(locals) { }); } -module.exports = postGenerator; +export = postGenerator; diff --git a/lib/plugins/helper/css.js b/lib/plugins/helper/css.ts similarity index 80% rename from lib/plugins/helper/css.js rename to lib/plugins/helper/css.ts index 0e728bd1b6..b7a86f5524 100644 --- a/lib/plugins/helper/css.js +++ b/lib/plugins/helper/css.ts @@ -1,7 +1,5 @@ -'use strict'; - -const { htmlTag, url_for } = require('hexo-util'); -const { default: moize } = require('moize'); +import { htmlTag, url_for } from 'hexo-util'; +import moize from 'moize'; function cssHelper(...args) { let result = '\n'; @@ -23,7 +21,7 @@ function cssHelper(...args) { return result; } -module.exports = moize(cssHelper, { +export = moize(cssHelper, { maxSize: 10, isDeepEqual: true }); diff --git a/lib/plugins/helper/date.js b/lib/plugins/helper/date.ts similarity index 82% rename from lib/plugins/helper/date.js rename to lib/plugins/helper/date.ts index 8235e5fff4..b347770dc8 100644 --- a/lib/plugins/helper/date.js +++ b/lib/plugins/helper/date.ts @@ -1,8 +1,6 @@ -'use strict'; - -const moment = require('moment-timezone'); +import moment from 'moment-timezone'; const { isMoment } = moment; -const { default: moize } = require('moize'); +import moize from 'moize'; const isDate = value => typeof value === 'object' && value instanceof Date && !isNaN(value.getTime()); @@ -10,7 +8,7 @@ const isDate = value => function getMoment(date, lang, timezone) { if (date == null) date = moment(); if (!isMoment(date)) date = moment(isDate(date) ? date : new Date(date)); - lang = toMomentLocale(lang); + lang = _toMomentLocale(lang); if (lang) date = date.locale(lang); if (timezone) date = date.tz(timezone); @@ -74,7 +72,7 @@ function getLanguage(ctx) { * * Moment defined locales: https://github.com/moment/moment/tree/master/locale */ -function toMomentLocale(lang) { +function _toMomentLocale(lang) { if (lang === undefined) { return undefined; } @@ -87,11 +85,11 @@ function toMomentLocale(lang) { return lang.toLowerCase().replace('_', '-'); } -exports.date = dateHelper; -exports.date_xml = toISOString; -exports.time = timeHelper; -exports.full_date = fullDateHelper; -exports.relative_date = relativeDateHelper; -exports.time_tag = timeTagHelper; -exports.moment = moment; -exports.toMomentLocale = moize.shallow(toMomentLocale); +export {dateHelper as date}; +export {toISOString as date_xml}; +export {timeHelper as time}; +export {fullDateHelper as full_date}; +export {relativeDateHelper as relative_date}; +export {timeTagHelper as time_tag}; +export {moment}; +export const toMomentLocale = moize.shallow(_toMomentLocale); diff --git a/lib/plugins/helper/debug.js b/lib/plugins/helper/debug.ts similarity index 69% rename from lib/plugins/helper/debug.js rename to lib/plugins/helper/debug.ts index 22b7935385..ba4a96983f 100644 --- a/lib/plugins/helper/debug.js +++ b/lib/plugins/helper/debug.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { inspect } = require('util'); +import { inspect } from 'util'; // this format object as string, resolves circular reference function inspectObject(object, options) { @@ -12,5 +10,5 @@ function log(...args) { return Reflect.apply(console.log, null, args); } -exports.inspectObject = inspectObject; -exports.log = log; +export {inspectObject}; +export {log}; diff --git a/lib/plugins/helper/favicon_tag.js b/lib/plugins/helper/favicon_tag.ts similarity index 54% rename from lib/plugins/helper/favicon_tag.js rename to lib/plugins/helper/favicon_tag.ts index e2b756bcc8..579c04379a 100644 --- a/lib/plugins/helper/favicon_tag.js +++ b/lib/plugins/helper/favicon_tag.ts @@ -1,9 +1,7 @@ -'use strict'; - -const { url_for } = require('hexo-util'); +import { url_for } from 'hexo-util'; function faviconTagHelper(path) { return ``; } -module.exports = faviconTagHelper; +export = faviconTagHelper; diff --git a/lib/plugins/helper/feed_tag.js b/lib/plugins/helper/feed_tag.ts similarity index 85% rename from lib/plugins/helper/feed_tag.js rename to lib/plugins/helper/feed_tag.ts index a72af70f12..8fccfc7738 100644 --- a/lib/plugins/helper/feed_tag.js +++ b/lib/plugins/helper/feed_tag.ts @@ -1,14 +1,17 @@ -'use strict'; - -const { url_for } = require('hexo-util'); -const { default: moize } = require('moize'); +import { url_for } from 'hexo-util'; +import moize from 'moize'; const feedFn = (str = '') => { if (str) return str.replace(/2$/, ''); return str; }; -function makeFeedTag(path, options = {}, configFeed, configTitle) { +interface Options { + title?: string; + type?: string; +} + +function makeFeedTag(path, options: Options = {}, configFeed?, configTitle?) { const title = options.title || configTitle; if (path) { @@ -48,4 +51,4 @@ function feedTagHelper(path, options = {}) { return moize.deep(makeFeedTag.bind(this))(path, options, config.feed, config.title); } -module.exports = feedTagHelper; +export = feedTagHelper; diff --git a/lib/plugins/helper/format.js b/lib/plugins/helper/format.js deleted file mode 100644 index e80f54b50f..0000000000 --- a/lib/plugins/helper/format.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; - -const { stripHTML, wordWrap, truncate, escapeHTML } = require('hexo-util'); -const titlecase = require('titlecase'); - -exports.strip_html = stripHTML; -exports.stripHTML = stripHTML; - -exports.trim = str => str.trim(); - -exports.titlecase = titlecase; - -exports.word_wrap = wordWrap; -exports.wordWrap = wordWrap; - -exports.truncate = truncate; - -exports.escape_html = escapeHTML; -exports.escapeHTML = escapeHTML; diff --git a/lib/plugins/helper/format.ts b/lib/plugins/helper/format.ts new file mode 100644 index 0000000000..c9372b507e --- /dev/null +++ b/lib/plugins/helper/format.ts @@ -0,0 +1,15 @@ +import { stripHTML, wordWrap, truncate, escapeHTML } from 'hexo-util'; +import titlecase from 'titlecase'; +export {stripHTML as strip_html}; +export {stripHTML}; + +export function trim(str) { + return str.trim(); +} + +export {titlecase}; +export {wordWrap as word_wrap}; +export {wordWrap}; +export {truncate}; +export {escapeHTML as escape_html}; +export {escapeHTML}; diff --git a/lib/plugins/helper/fragment_cache.js b/lib/plugins/helper/fragment_cache.ts similarity index 78% rename from lib/plugins/helper/fragment_cache.js rename to lib/plugins/helper/fragment_cache.ts index 19e4f675a0..1c38229e0c 100644 --- a/lib/plugins/helper/fragment_cache.js +++ b/lib/plugins/helper/fragment_cache.ts @@ -1,7 +1,7 @@ -'use strict'; -const { Cache } = require('hexo-util'); -module.exports = ctx => { +import { Cache } from 'hexo-util'; + +export = ctx => { const cache = new Cache(); // reset cache for watch mode diff --git a/lib/plugins/helper/full_url_for.js b/lib/plugins/helper/full_url_for.js deleted file mode 100755 index 997db74ab6..0000000000 --- a/lib/plugins/helper/full_url_for.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; -const { full_url_for } = require('hexo-util'); - -module.exports = function(path) { - return full_url_for.call(this, path); -}; diff --git a/lib/plugins/helper/full_url_for.ts b/lib/plugins/helper/full_url_for.ts new file mode 100644 index 0000000000..4e77338082 --- /dev/null +++ b/lib/plugins/helper/full_url_for.ts @@ -0,0 +1,6 @@ + +import { full_url_for } from 'hexo-util'; + +export = function(path) { + return full_url_for.call(this, path); +} diff --git a/lib/plugins/helper/gravatar.js b/lib/plugins/helper/gravatar.js deleted file mode 100644 index 888a5eef30..0000000000 --- a/lib/plugins/helper/gravatar.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -const { gravatar } = require('hexo-util'); - -module.exports = gravatar; diff --git a/lib/plugins/helper/gravatar.ts b/lib/plugins/helper/gravatar.ts new file mode 100644 index 0000000000..5500335216 --- /dev/null +++ b/lib/plugins/helper/gravatar.ts @@ -0,0 +1,2 @@ +import { gravatar } from 'hexo-util'; +export = gravatar; diff --git a/lib/plugins/helper/image_tag.js b/lib/plugins/helper/image_tag.js deleted file mode 100644 index 5ca27c1f5c..0000000000 --- a/lib/plugins/helper/image_tag.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; - -const { htmlTag, url_for } = require('hexo-util'); - -function imageTagHelper(path, options = {}) { - const attrs = Object.assign({ - src: url_for.call(this, path) - }, options); - - if (attrs.class && Array.isArray(attrs.class)) { - attrs.class = attrs.class.join(' '); - } - - return htmlTag('img', attrs); -} - -module.exports = imageTagHelper; diff --git a/lib/plugins/helper/image_tag.ts b/lib/plugins/helper/image_tag.ts new file mode 100644 index 0000000000..402c6e3714 --- /dev/null +++ b/lib/plugins/helper/image_tag.ts @@ -0,0 +1,26 @@ +import { htmlTag, url_for } from 'hexo-util'; + +interface Options { + src?: string; + class?: string | string[]; +} + +interface Attrs { + src?: string; + class?: string; + [key: string]: string | undefined; +} + +function imageTagHelper(path: string, options: Options = {}) { + const attrs = Object.assign({ + src: url_for.call(this, path) as string + }, options); + + if (attrs.class && Array.isArray(attrs.class)) { + attrs.class = attrs.class.join(' '); + } + + return htmlTag('img', attrs as Attrs); +} + +export = imageTagHelper; diff --git a/lib/plugins/helper/index.js b/lib/plugins/helper/index.ts similarity index 98% rename from lib/plugins/helper/index.js rename to lib/plugins/helper/index.ts index fc86aa6074..79adc27b7d 100644 --- a/lib/plugins/helper/index.js +++ b/lib/plugins/helper/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { helper } = ctx.extend; const date = require('./date'); diff --git a/lib/plugins/helper/is.js b/lib/plugins/helper/is.ts similarity index 81% rename from lib/plugins/helper/is.js rename to lib/plugins/helper/is.ts index 9f74f3b6d6..1f843cf3ff 100644 --- a/lib/plugins/helper/is.js +++ b/lib/plugins/helper/is.ts @@ -1,5 +1,3 @@ -'use strict'; - function isCurrentHelper(path = '/', strict) { const currentPath = this.path.replace(/^[^/].*/, '/$&'); @@ -81,13 +79,13 @@ function isTagHelper(tag) { return Boolean(this.page.tag); } -exports.current = isCurrentHelper; -exports.home = isHomeHelper; -exports.home_first_page = isHomeFirstPageHelper; -exports.post = isPostHelper; -exports.page = isPageHelper; -exports.archive = isArchiveHelper; -exports.year = isYearHelper; -exports.month = isMonthHelper; -exports.category = isCategoryHelper; -exports.tag = isTagHelper; +export {isCurrentHelper as current}; +export {isHomeHelper as home}; +export {isHomeFirstPageHelper as home_first_page}; +export {isPostHelper as post}; +export {isPageHelper as page}; +export {isArchiveHelper as archive}; +export {isYearHelper as year}; +export {isMonthHelper as month}; +export {isCategoryHelper as category}; +export {isTagHelper as tag}; diff --git a/lib/plugins/helper/js.js b/lib/plugins/helper/js.ts similarity index 80% rename from lib/plugins/helper/js.js rename to lib/plugins/helper/js.ts index 1ab2ebcff4..120d1738bb 100644 --- a/lib/plugins/helper/js.js +++ b/lib/plugins/helper/js.ts @@ -1,7 +1,5 @@ -'use strict'; - -const { htmlTag, url_for } = require('hexo-util'); -const { default: moize } = require('moize'); +import { htmlTag, url_for } from 'hexo-util'; +import moize from 'moize'; function jsHelper(...args) { let result = '\n'; @@ -23,7 +21,7 @@ function jsHelper(...args) { return result; } -module.exports = moize(jsHelper, { +export = moize(jsHelper, { maxSize: 10, isDeepEqual: true }); diff --git a/lib/plugins/helper/link_to.js b/lib/plugins/helper/link_to.js deleted file mode 100644 index 09daed2176..0000000000 --- a/lib/plugins/helper/link_to.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -const { htmlTag, url_for } = require('hexo-util'); - -function linkToHelper(path, text, options = {}) { - if (typeof options === 'boolean') options = {external: options}; - - if (!text) text = path.replace(/^https?:\/\/|\/$/g, ''); - - const attrs = Object.assign({ - href: url_for.call(this, path), - title: text - }, options); - - if (attrs.external) { - attrs.target = '_blank'; - attrs.rel = 'noopener'; - attrs.external = null; - } - - if (attrs.class && Array.isArray(attrs.class)) { - attrs.class = attrs.class.join(' '); - } - - return htmlTag('a', attrs, text); -} - -module.exports = linkToHelper; diff --git a/lib/plugins/helper/link_to.ts b/lib/plugins/helper/link_to.ts new file mode 100644 index 0000000000..cb0792d172 --- /dev/null +++ b/lib/plugins/helper/link_to.ts @@ -0,0 +1,45 @@ +import { htmlTag, url_for } from 'hexo-util'; + +interface Options { + href?: string; + title?: string; + external?: boolean | null; + class?: string | string[]; + target?: string; + rel?: string; +} + +interface Attrs { + href: string; + title: string; + external?: boolean | null; + class?: string; + target?: string; + rel?: string; + [key: string]: string | boolean | null | undefined; +} + +function linkToHelper(path: string, text: string, options: Options | boolean = {}) { + if (typeof options === 'boolean') options = {external: options}; + + if (!text) text = path.replace(/^https?:\/\/|\/$/g, ''); + + const attrs = Object.assign({ + href: url_for.call(this, path) as string, + title: text + }, options); + + if (attrs.external) { + attrs.target = '_blank'; + attrs.rel = 'noopener'; + attrs.external = null; + } + + if (attrs.class && Array.isArray(attrs.class)) { + attrs.class = attrs.class.join(' '); + } + + return htmlTag('a', attrs as Attrs, text); +} + +export = linkToHelper; diff --git a/lib/plugins/helper/list_archives.js b/lib/plugins/helper/list_archives.ts similarity index 84% rename from lib/plugins/helper/list_archives.js rename to lib/plugins/helper/list_archives.ts index 89b2b69414..2572a25cb7 100644 --- a/lib/plugins/helper/list_archives.js +++ b/lib/plugins/helper/list_archives.ts @@ -1,9 +1,25 @@ -'use strict'; +import { toMomentLocale } from './date'; +import { url_for } from 'hexo-util'; + +interface Options { + format?: string; + type?: string; + style?: string; + transform?: (name: string) => string; + separator?: string; + show_count?: boolean; + class?: string; + order?: number; +} -const { toMomentLocale } = require('./date'); -const { url_for } = require('hexo-util'); +interface Data { + name: string; + year: number; + month: number; + count: number; +} -function listArchivesHelper(options = {}) { +function listArchivesHelper(options: Options = {}) { const { config } = this; const archiveDir = config.archive_dir; const { timezone } = config; @@ -27,7 +43,7 @@ function listArchivesHelper(options = {}) { const posts = this.site.posts.sort('date', order); if (!posts.length) return result; - const data = []; + const data: Data[] = []; let length = 0; posts.forEach(post => { @@ -105,4 +121,4 @@ function listArchivesHelper(options = {}) { return result; } -module.exports = listArchivesHelper; +export = listArchivesHelper; diff --git a/lib/plugins/helper/list_categories.js b/lib/plugins/helper/list_categories.ts similarity index 93% rename from lib/plugins/helper/list_categories.js rename to lib/plugins/helper/list_categories.ts index 51455f2294..ff248d6bf3 100644 --- a/lib/plugins/helper/list_categories.js +++ b/lib/plugins/helper/list_categories.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { url_for } = require('hexo-util'); +import { url_for } from 'hexo-util'; function listCategoriesHelper(categories, options) { if (!options && (!categories || !Object.prototype.hasOwnProperty.call(categories, 'length'))) { @@ -21,7 +19,7 @@ function listCategoriesHelper(categories, options) { const childrenIndicator = Object.prototype.hasOwnProperty.call(options, 'children_indicator') ? options.children_indicator : false; const prepareQuery = parent => { - const query = {}; + const query: { parent?: any } = {}; if (parent) { query.parent = parent; @@ -32,7 +30,7 @@ function listCategoriesHelper(categories, options) { return categories.find(query).sort(orderby, order); }; - const hierarchicalList = (level, parent) => { + const hierarchicalList = (level: number, parent?: any) => { let result = ''; prepareQuery(parent).forEach((cat, i) => { @@ -77,7 +75,7 @@ function listCategoriesHelper(categories, options) { return result; }; - const flatList = (level, parent) => { + const flatList = (level: number, parent?: any) => { let result = ''; prepareQuery(parent).forEach((cat, i) => { @@ -107,4 +105,4 @@ function listCategoriesHelper(categories, options) { return flatList(0); } -module.exports = listCategoriesHelper; +export = listCategoriesHelper; diff --git a/lib/plugins/helper/list_posts.js b/lib/plugins/helper/list_posts.ts similarity index 93% rename from lib/plugins/helper/list_posts.js rename to lib/plugins/helper/list_posts.ts index 156ebff2fc..a3d9b9b5ca 100644 --- a/lib/plugins/helper/list_posts.js +++ b/lib/plugins/helper/list_posts.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { url_for } = require('hexo-util'); +import { url_for } from 'hexo-util'; function listPostsHelper(posts, options) { if (!options && (!posts || !Object.prototype.hasOwnProperty.call(posts, 'length'))) { @@ -55,4 +53,4 @@ function listPostsHelper(posts, options) { return result; } -module.exports = listPostsHelper; +export = listPostsHelper; diff --git a/lib/plugins/helper/list_tags.js b/lib/plugins/helper/list_tags.ts similarity index 94% rename from lib/plugins/helper/list_tags.js rename to lib/plugins/helper/list_tags.ts index c75626f720..b7b0d0b523 100644 --- a/lib/plugins/helper/list_tags.js +++ b/lib/plugins/helper/list_tags.ts @@ -1,9 +1,7 @@ -'use strict'; +import { url_for, escapeHTML } from 'hexo-util'; +import moize from 'moize'; -const { url_for, escapeHTML } = require('hexo-util'); -const { default: moize } = require('moize'); - -function listTagsHelper(tags, options) { +function listTagsHelper(tags, options?) { if (!options && (!tags || !Object.prototype.hasOwnProperty.call(tags, 'length'))) { options = tags; tags = this.site.tags; @@ -107,4 +105,4 @@ function listTagsHelperFactory(tags, options) { }).call(this, tags, options); } -module.exports = listTagsHelperFactory; +export = listTagsHelperFactory; diff --git a/lib/plugins/helper/mail_to.js b/lib/plugins/helper/mail_to.ts similarity index 60% rename from lib/plugins/helper/mail_to.js rename to lib/plugins/helper/mail_to.ts index 9752f0055d..90f9ef88c9 100644 --- a/lib/plugins/helper/mail_to.js +++ b/lib/plugins/helper/mail_to.ts @@ -1,9 +1,20 @@ -'use strict'; +import { htmlTag } from 'hexo-util'; +import moize from 'moize'; -const { htmlTag } = require('hexo-util'); -const { default: moize } = require('moize'); +interface Options { + href?: string; + title?: string; + class?: string | string[]; +} + +interface Attrs { + href: string; + title: string; + class?: string; + [key: string]: string | boolean | null | undefined; +} -function mailToHelper(path, text, options = {}) { +function mailToHelper(path, text, options: Options = {}) { if (Array.isArray(path)) path = path.join(','); if (!text) text = path; @@ -30,10 +41,10 @@ function mailToHelper(path, text, options = {}) { const querystring = new URLSearchParams(data).toString(); if (querystring) attrs.href += `?${querystring}`; - return htmlTag('a', attrs, text); + return htmlTag('a', attrs as Attrs, text); } -module.exports = moize(mailToHelper, { +export = moize(mailToHelper, { maxSize: 10, isDeepEqual: true }); diff --git a/lib/plugins/helper/markdown.js b/lib/plugins/helper/markdown.ts similarity index 65% rename from lib/plugins/helper/markdown.js rename to lib/plugins/helper/markdown.ts index 7df352843d..956425f072 100644 --- a/lib/plugins/helper/markdown.js +++ b/lib/plugins/helper/markdown.ts @@ -1,7 +1,5 @@ -'use strict'; - function markdownHelper(text, options) { return this.render(text, 'markdown', options); } -module.exports = markdownHelper; +export = markdownHelper; diff --git a/lib/plugins/helper/meta_generator.js b/lib/plugins/helper/meta_generator.ts old mode 100755 new mode 100644 similarity index 66% rename from lib/plugins/helper/meta_generator.js rename to lib/plugins/helper/meta_generator.ts index 20b7613939..4b0036c558 --- a/lib/plugins/helper/meta_generator.js +++ b/lib/plugins/helper/meta_generator.ts @@ -1,7 +1,5 @@ -'use strict'; - function metaGeneratorHelper() { return ``; } -module.exports = metaGeneratorHelper; +export = metaGeneratorHelper; diff --git a/lib/plugins/helper/number_format.js b/lib/plugins/helper/number_format.ts similarity index 81% rename from lib/plugins/helper/number_format.js rename to lib/plugins/helper/number_format.ts index c6c2c0985d..350e1b1129 100644 --- a/lib/plugins/helper/number_format.js +++ b/lib/plugins/helper/number_format.ts @@ -1,15 +1,19 @@ -'use strict'; +interface Options { + delimiter?: string; + separator?: string; + precision?: number; +} -function numberFormatHelper(num, options = {}) { +function numberFormatHelper(num: number, options: Options = {}) { const split = num.toString().split('.'); - let before = split.shift(); + let before = split.shift() as string; let after = split.length ? split[0] : ''; const delimiter = options.delimiter || ','; const separator = options.separator || '.'; const { precision } = options; if (delimiter) { - const beforeArr = []; + const beforeArr: string[] = []; const beforeLength = before.length; const beforeFirst = beforeLength % 3; @@ -46,4 +50,4 @@ function numberFormatHelper(num, options = {}) { return before + (after ? separator + after : ''); } -module.exports = numberFormatHelper; +export = numberFormatHelper; diff --git a/lib/plugins/helper/open_graph.js b/lib/plugins/helper/open_graph.ts similarity index 85% rename from lib/plugins/helper/open_graph.js rename to lib/plugins/helper/open_graph.ts index e9c3eb0dbe..9209eeda63 100644 --- a/lib/plugins/helper/open_graph.js +++ b/lib/plugins/helper/open_graph.ts @@ -1,8 +1,6 @@ -'use strict'; - -const { isMoment, isDate } = require('moment'); -const { encodeURL, prettyUrls, stripHTML, escapeHTML } = require('hexo-util'); -const { default: moize } = require('moize'); +import { isMoment, isDate } from 'moment'; +import { encodeURL, prettyUrls, stripHTML, escapeHTML } from 'hexo-util'; +import moize from 'moize'; const localeMap = { 'en': 'en_US', @@ -36,7 +34,7 @@ const localeToTerritory = moize.shallow(str => { } }); -const meta = (name, content, escape) => { +const meta = (name, content, escape?: boolean) => { if (escape !== false && typeof content === 'string') { content = escapeHTML(content); } @@ -45,7 +43,7 @@ const meta = (name, content, escape) => { return `\n`; }; -const og = (name, content, escape) => { +const og = (name, content?: string, escape?: boolean) => { if (escape !== false && typeof content === 'string') { content = escapeHTML(content); } @@ -54,7 +52,27 @@ const og = (name, content, escape) => { return `\n`; }; -function openGraphHelper(options = {}) { +interface Options { + image?: string; + images?: string[]; + description?: string; + title?: string; + type?: string; + url?: string; + site_name?: string; + twitter_card?: string; + date?: boolean; + updated?: boolean; + language?: string; + author?: string; + twitter_image?: string; + twitter_id?: string; + twitter_site?: string; + fb_admins?: string; + fb_app_id?: string; +} + +function openGraphHelper(options: Options = {}) { const { config, page } = this; const { content } = page; let images = options.image || options.images || page.photos || []; @@ -151,7 +169,7 @@ function openGraphHelper(options = {}) { result += meta('twitter:card', twitterCard); if (options.twitter_image) { - let twitter_image = options.twitter_image; + let twitter_image: string | URL = options.twitter_image; twitter_image = new URL(twitter_image, url || config.url); result += meta('twitter:image', twitter_image, false); } else if (images.length) { @@ -180,4 +198,4 @@ function openGraphHelper(options = {}) { return result.trim(); } -module.exports = openGraphHelper; +export = openGraphHelper; diff --git a/lib/plugins/helper/paginator.js b/lib/plugins/helper/paginator.ts similarity index 87% rename from lib/plugins/helper/paginator.js rename to lib/plugins/helper/paginator.ts index 662c61022c..83a12ff2c1 100644 --- a/lib/plugins/helper/paginator.js +++ b/lib/plugins/helper/paginator.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { htmlTag, url_for } = require('hexo-util'); +import { htmlTag, url_for } from 'hexo-util'; const createLink = (options, ctx) => { const { base, format } = options; @@ -88,7 +86,28 @@ const pagenasionPartShow = (tags, options, ctx) => { } }; -function paginatorHelper(options = {}) { +interface Options { + base?: string; + current?: number; + format?: string; + total?: number; + end_size?: number; + mid_size?: number; + space?: string; + next_text?: string; + prev_text?: string; + prev_next?: boolean; + escape?: boolean; + page_class?: string; + current_class?: string; + space_class?: string; + prev_class?: string; + next_class?: string; + force_prev_next?: boolean; + show_all?: boolean; +} + +function paginatorHelper(options: Options = {}) { options = Object.assign({ base: this.page.base || '', current: this.page.current || 0, @@ -150,4 +169,4 @@ function paginatorHelper(options = {}) { return tags.join(''); } -module.exports = paginatorHelper; +export = paginatorHelper; diff --git a/lib/plugins/helper/partial.js b/lib/plugins/helper/partial.ts similarity index 82% rename from lib/plugins/helper/partial.js rename to lib/plugins/helper/partial.ts index bc3994189c..d548a58ba9 100644 --- a/lib/plugins/helper/partial.js +++ b/lib/plugins/helper/partial.ts @@ -1,8 +1,11 @@ -'use strict'; +import { dirname, join } from 'path'; -const { dirname, join } = require('path'); +interface Options { + cache?: boolean | string; + only?: boolean; +} -module.exports = ctx => function partial(name, locals, options = {}) { +export = ctx => function partial(name, locals, options: Options = {}) { if (typeof name !== 'string') throw new TypeError('name must be a string!'); const { cache } = options; diff --git a/lib/plugins/helper/relative_url.js b/lib/plugins/helper/relative_url.js deleted file mode 100644 index db1fba37fc..0000000000 --- a/lib/plugins/helper/relative_url.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -const { relative_url } = require('hexo-util'); - -module.exports = function(from, to) { - return relative_url(from, to); -}; diff --git a/lib/plugins/helper/relative_url.ts b/lib/plugins/helper/relative_url.ts new file mode 100644 index 0000000000..631a9946fd --- /dev/null +++ b/lib/plugins/helper/relative_url.ts @@ -0,0 +1,5 @@ +import { relative_url } from 'hexo-util'; + +export = function(from, to) { + return relative_url(from, to); +} diff --git a/lib/plugins/helper/render.js b/lib/plugins/helper/render.js deleted file mode 100644 index f71bdb2917..0000000000 --- a/lib/plugins/helper/render.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; - -module.exports = ctx => function render(text, engine, options) { - return ctx.render.renderSync({ - text, - engine - }, options); -}; diff --git a/lib/plugins/helper/render.ts b/lib/plugins/helper/render.ts new file mode 100644 index 0000000000..9f8473efb3 --- /dev/null +++ b/lib/plugins/helper/render.ts @@ -0,0 +1,6 @@ +export = ctx => function render(text, engine, options) { + return ctx.render.renderSync({ + text, + engine + }, options); +}; diff --git a/lib/plugins/helper/search_form.js b/lib/plugins/helper/search_form.ts similarity index 72% rename from lib/plugins/helper/search_form.js rename to lib/plugins/helper/search_form.ts index f90a99b6d7..6414615e82 100644 --- a/lib/plugins/helper/search_form.js +++ b/lib/plugins/helper/search_form.ts @@ -1,8 +1,12 @@ -'use strict'; +import moize from 'moize'; -const { default: moize } = require('moize'); +interface Options { + class?: string; + text?: string; + button?: string | boolean; +} -function searchFormHelper(options = {}) { +function searchFormHelper(options: Options = {}) { const { config } = this; const className = options.class || 'search-form'; const { text = 'Search', button } = options; @@ -10,4 +14,4 @@ function searchFormHelper(options = {}) { return `
${button ? `` : ''}
`; } -module.exports = moize.deep(searchFormHelper); +export = moize.deep(searchFormHelper); diff --git a/lib/plugins/helper/tagcloud.js b/lib/plugins/helper/tagcloud.ts similarity index 93% rename from lib/plugins/helper/tagcloud.js rename to lib/plugins/helper/tagcloud.ts index c6ee5f718d..0b9a58d0b0 100644 --- a/lib/plugins/helper/tagcloud.js +++ b/lib/plugins/helper/tagcloud.ts @@ -1,9 +1,7 @@ -'use strict'; +import { Color, url_for } from 'hexo-util'; +import moize from 'moize'; -const { Color, url_for } = require('hexo-util'); -const { default: moize } = require('moize'); - -function tagcloudHelper(tags, options) { +function tagcloudHelper(tags, options?) { if (!options && (!tags || !Object.prototype.hasOwnProperty.call(tags, 'length'))) { options = tags; tags = this.site.tags; @@ -94,4 +92,4 @@ function tagcloudHelperFactory(tags, options) { }).call(this, tags, options); } -module.exports = tagcloudHelperFactory; +export = tagcloudHelperFactory; diff --git a/lib/plugins/helper/toc.js b/lib/plugins/helper/toc.ts similarity index 86% rename from lib/plugins/helper/toc.js rename to lib/plugins/helper/toc.ts index e055ffd6f2..4abec4d30b 100644 --- a/lib/plugins/helper/toc.js +++ b/lib/plugins/helper/toc.ts @@ -1,8 +1,19 @@ -'use strict'; - -const { tocObj, escapeHTML, encodeURL } = require('hexo-util'); +import { tocObj, escapeHTML, encodeURL } from 'hexo-util'; + +interface Options { + min_depth?: number; + max_depth?: number; + class?: string; + class_item?: string; + class_link?: string; + class_text?: string; + class_child?: string; + class_number?: string; + class_level?: string; + list_number?: boolean; +} -function tocHelper(str, options = {}) { +function tocHelper(str, options: Options = {}) { options = Object.assign({ min_depth: 1, max_depth: 6, @@ -91,4 +102,4 @@ function tocHelper(str, options = {}) { return result; } -module.exports = tocHelper; +export = tocHelper; diff --git a/lib/plugins/helper/url_for.js b/lib/plugins/helper/url_for.js deleted file mode 100644 index a31379a29b..0000000000 --- a/lib/plugins/helper/url_for.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -const { url_for } = require('hexo-util'); - -module.exports = function(path, options) { - return url_for.call(this, path, options); -}; diff --git a/lib/plugins/helper/url_for.ts b/lib/plugins/helper/url_for.ts new file mode 100644 index 0000000000..49e7a5f124 --- /dev/null +++ b/lib/plugins/helper/url_for.ts @@ -0,0 +1,5 @@ +import { url_for } from 'hexo-util'; + +export = function(path, options) { + return url_for.call(this, path, options); +} diff --git a/lib/plugins/highlight/highlight.js b/lib/plugins/highlight/highlight.ts similarity index 98% rename from lib/plugins/highlight/highlight.js rename to lib/plugins/highlight/highlight.ts index c90ccd7994..787017fcf7 100644 --- a/lib/plugins/highlight/highlight.js +++ b/lib/plugins/highlight/highlight.ts @@ -1,5 +1,3 @@ -'use strict'; - // Lazy require highlight.js let highlight; diff --git a/lib/plugins/highlight/index.js b/lib/plugins/highlight/index.ts similarity index 92% rename from lib/plugins/highlight/index.js rename to lib/plugins/highlight/index.ts index 9dc22fd7d4..2efad0cbf6 100644 --- a/lib/plugins/highlight/index.js +++ b/lib/plugins/highlight/index.ts @@ -1,5 +1,3 @@ -'use strict'; - module.exports = ctx => { const { highlight } = ctx.extend; diff --git a/lib/plugins/highlight/prism.js b/lib/plugins/highlight/prism.ts similarity index 98% rename from lib/plugins/highlight/prism.js rename to lib/plugins/highlight/prism.ts index 7d46461c96..1e37674fd0 100644 --- a/lib/plugins/highlight/prism.js +++ b/lib/plugins/highlight/prism.ts @@ -1,5 +1,3 @@ -'use strict'; - // Lazy require prismjs let prismHighlight; diff --git a/lib/plugins/injector/index.js b/lib/plugins/injector/index.ts similarity index 66% rename from lib/plugins/injector/index.js rename to lib/plugins/injector/index.ts index be1a9aaca9..5c7d54f6ac 100644 --- a/lib/plugins/injector/index.js +++ b/lib/plugins/injector/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { // eslint-disable-next-line no-unused-vars const { injector } = ctx.extend; }; diff --git a/lib/plugins/processor/asset.js b/lib/plugins/processor/asset.ts similarity index 88% rename from lib/plugins/processor/asset.js rename to lib/plugins/processor/asset.ts index 113dab4e8d..9693bbaeb5 100644 --- a/lib/plugins/processor/asset.js +++ b/lib/plugins/processor/asset.ts @@ -1,13 +1,11 @@ -'use strict'; - -const { timezone, toDate, isExcludedFile, isMatch } = require('./common'); -const Promise = require('bluebird'); -const { parse: yfm } = require('hexo-front-matter'); -const { extname, relative } = require('path'); -const { Pattern } = require('hexo-util'); -const { magenta } = require('picocolors'); - -module.exports = ctx => { +import { timezone, toDate, isExcludedFile, isMatch } from './common'; +import Promise from 'bluebird'; +import { parse as yfm } from 'hexo-front-matter'; +import { extname, relative } from 'path'; +import { Pattern } from 'hexo-util'; +import { magenta } from 'picocolors'; + +export = ctx => { return { pattern: new Pattern(path => { if (isExcludedFile(path, ctx.config)) return; diff --git a/lib/plugins/processor/common.js b/lib/plugins/processor/common.ts similarity index 71% rename from lib/plugins/processor/common.js rename to lib/plugins/processor/common.ts index e29c05ecb4..c981536598 100644 --- a/lib/plugins/processor/common.js +++ b/lib/plugins/processor/common.ts @@ -1,8 +1,6 @@ -'use strict'; - -const { Pattern } = require('hexo-util'); -const moment = require('moment-timezone'); -const micromatch = require('micromatch'); +import { Pattern } from 'hexo-util'; +import moment from 'moment-timezone'; +import micromatch from 'micromatch'; const DURATION_MINUTE = 1000 * 60; @@ -27,16 +25,16 @@ function isExcludedFile(path, config) { return false; } -exports.ignoreTmpAndHiddenFile = new Pattern(path => { +export const ignoreTmpAndHiddenFile = new Pattern(path => { if (isTmpFile(path) || isHiddenFile(path)) return false; return true; }); -exports.isTmpFile = isTmpFile; -exports.isHiddenFile = isHiddenFile; -exports.isExcludedFile = isExcludedFile; +export {isTmpFile}; +export {isHiddenFile}; +export {isExcludedFile}; -exports.toDate = date => { +export function toDate(date) { if (!date || moment.isMoment(date)) return date; if (!(date instanceof Date)) { @@ -46,9 +44,9 @@ exports.toDate = date => { if (isNaN(date.getTime())) return; return date; -}; +} -exports.timezone = (date, timezone) => { +export function timezone(date, timezone) { if (moment.isMoment(date)) date = date.toDate(); const offset = date.getTimezoneOffset(); @@ -57,6 +55,6 @@ exports.timezone = (date, timezone) => { const diff = (offset - target) * DURATION_MINUTE; return new Date(ms - diff); -}; +} -exports.isMatch = isMatch; +export {isMatch}; diff --git a/lib/plugins/processor/data.js b/lib/plugins/processor/data.ts similarity index 83% rename from lib/plugins/processor/data.js rename to lib/plugins/processor/data.ts index e6878f24b5..7757e7c99c 100644 --- a/lib/plugins/processor/data.js +++ b/lib/plugins/processor/data.ts @@ -1,9 +1,7 @@ -'use strict'; +import { Pattern } from 'hexo-util'; +import { extname } from 'path'; -const { Pattern } = require('hexo-util'); -const { extname } = require('path'); - -module.exports = ctx => ({ +export = ctx => ({ pattern: new Pattern('_data/*path'), process: function dataProcessor(file) { diff --git a/lib/plugins/processor/index.js b/lib/plugins/processor/index.ts similarity index 84% rename from lib/plugins/processor/index.js rename to lib/plugins/processor/index.ts index caa18dbaca..1161ff7730 100644 --- a/lib/plugins/processor/index.js +++ b/lib/plugins/processor/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { processor } = ctx.extend; function register(name) { diff --git a/lib/plugins/processor/post.js b/lib/plugins/processor/post.ts similarity index 94% rename from lib/plugins/processor/post.js rename to lib/plugins/processor/post.ts index 4e61712800..dca6306e62 100644 --- a/lib/plugins/processor/post.js +++ b/lib/plugins/processor/post.ts @@ -1,12 +1,10 @@ -'use strict'; - -const { toDate, timezone, isExcludedFile, isTmpFile, isHiddenFile, isMatch } = require('./common'); -const Promise = require('bluebird'); -const { parse: yfm } = require('hexo-front-matter'); -const { extname, join } = require('path'); -const { stat, listDir } = require('hexo-fs'); -const { slugize, Pattern, Permalink } = require('hexo-util'); -const { magenta } = require('picocolors'); +import { toDate, timezone, isExcludedFile, isTmpFile, isHiddenFile, isMatch } from './common'; +import Promise from 'bluebird'; +import { parse as yfm } from 'hexo-front-matter'; +import { extname, join } from 'path'; +import { stat, listDir } from 'hexo-fs'; +import { slugize, Pattern, Permalink } from 'hexo-util'; +import { magenta } from 'picocolors'; const postDir = '_posts/'; const draftDir = '_drafts/'; @@ -22,7 +20,7 @@ const preservedKeys = { hash: true }; -module.exports = ctx => { +export = ctx => { return { pattern: new Pattern(path => { if (isTmpFile(path)) return; diff --git a/lib/plugins/renderer/index.js b/lib/plugins/renderer/index.ts similarity index 93% rename from lib/plugins/renderer/index.js rename to lib/plugins/renderer/index.ts index d9f03fe718..c5e6969601 100644 --- a/lib/plugins/renderer/index.js +++ b/lib/plugins/renderer/index.ts @@ -1,6 +1,4 @@ -'use strict'; - -module.exports = ctx => { +export = ctx => { const { renderer } = ctx.extend; const plain = require('./plain'); diff --git a/lib/plugins/renderer/json.js b/lib/plugins/renderer/json.ts similarity index 58% rename from lib/plugins/renderer/json.js rename to lib/plugins/renderer/json.ts index 8dbe42cacc..7c87cf6ecb 100644 --- a/lib/plugins/renderer/json.js +++ b/lib/plugins/renderer/json.ts @@ -1,7 +1,5 @@ -'use strict'; - function jsonRenderer(data) { return JSON.parse(data.text); } -module.exports = jsonRenderer; +export = jsonRenderer; diff --git a/lib/plugins/renderer/nunjucks.js b/lib/plugins/renderer/nunjucks.ts similarity index 90% rename from lib/plugins/renderer/nunjucks.js rename to lib/plugins/renderer/nunjucks.ts index b6760e0e00..be6cfc1781 100644 --- a/lib/plugins/renderer/nunjucks.js +++ b/lib/plugins/renderer/nunjucks.ts @@ -1,9 +1,7 @@ -'use strict'; - -const nunjucks = require('nunjucks'); -const { readFileSync } = require('hexo-fs'); -const { dirname } = require('path'); +import nunjucks from 'nunjucks'; +import { readFileSync } from 'hexo-fs'; +import { dirname } from 'path'; function toArray(value) { if (Array.isArray(value)) { @@ -67,4 +65,4 @@ njkRenderer.compile = data => { return locals => njkCompile(data).render(locals); }; -module.exports = njkRenderer; +export = njkRenderer; diff --git a/lib/plugins/renderer/plain.js b/lib/plugins/renderer/plain.ts similarity index 53% rename from lib/plugins/renderer/plain.js rename to lib/plugins/renderer/plain.ts index 2961bd8e7a..e1aa47f2df 100644 --- a/lib/plugins/renderer/plain.js +++ b/lib/plugins/renderer/plain.ts @@ -1,7 +1,5 @@ -'use strict'; - function plainRenderer(data) { return data.text; } -module.exports = plainRenderer; +export = plainRenderer; diff --git a/lib/plugins/renderer/yaml.js b/lib/plugins/renderer/yaml.ts similarity index 56% rename from lib/plugins/renderer/yaml.js rename to lib/plugins/renderer/yaml.ts index ad9a8a6c02..a8f0af4a34 100644 --- a/lib/plugins/renderer/yaml.js +++ b/lib/plugins/renderer/yaml.ts @@ -1,8 +1,6 @@ -'use strict'; - -const yaml = require('js-yaml'); -const { escape } = require('hexo-front-matter'); -const log = require('hexo-log').default(); +import yaml from 'js-yaml'; +import { escape } from 'hexo-front-matter'; +import logger from 'hexo-log'; let schema = {}; // FIXME: workaround for https://github.com/hexojs/hexo/issues/4917 @@ -10,7 +8,7 @@ try { schema = yaml.DEFAULT_SCHEMA.extend(require('js-yaml-js-types').all); } catch (e) { if (e instanceof yaml.YAMLException) { - log.warn('YAMLException: please see https://github.com/hexojs/hexo/issues/4917'); + logger().warn('YAMLException: please see https://github.com/hexojs/hexo/issues/4917'); } else { throw e; } @@ -20,4 +18,4 @@ function yamlHelper(data) { return yaml.load(escape(data.text), { schema }); } -module.exports = yamlHelper; +export = yamlHelper; diff --git a/lib/plugins/tag/asset_img.js b/lib/plugins/tag/asset_img.ts similarity index 81% rename from lib/plugins/tag/asset_img.js rename to lib/plugins/tag/asset_img.ts index 5189c28a27..e608b499ff 100644 --- a/lib/plugins/tag/asset_img.js +++ b/lib/plugins/tag/asset_img.ts @@ -1,7 +1,5 @@ -'use strict'; - -const img = require('./img'); -const { encodeURL } = require('hexo-util'); +import img from './img'; +import { encodeURL } from 'hexo-util'; /** * Asset image tag @@ -9,7 +7,7 @@ const { encodeURL } = require('hexo-util'); * Syntax: * {% asset_img [class names] slug [width] [height] [title text [alt text]]%} */ -module.exports = ctx => { +export = ctx => { const PostAsset = ctx.model('PostAsset'); return function assetImgTag(args) { diff --git a/lib/plugins/tag/asset_link.js b/lib/plugins/tag/asset_link.ts similarity index 88% rename from lib/plugins/tag/asset_link.js rename to lib/plugins/tag/asset_link.ts index 8f3225e297..eb07087625 100644 --- a/lib/plugins/tag/asset_link.js +++ b/lib/plugins/tag/asset_link.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { encodeURL, escapeHTML } = require('hexo-util'); +import { encodeURL, escapeHTML } from 'hexo-util'; /** * Asset link tag @@ -8,7 +6,7 @@ const { encodeURL, escapeHTML } = require('hexo-util'); * Syntax: * {% asset_link slug [title] [escape] %} */ -module.exports = ctx => { +export = ctx => { const PostAsset = ctx.model('PostAsset'); return function assetLinkTag(args) { diff --git a/lib/plugins/tag/asset_path.js b/lib/plugins/tag/asset_path.ts similarity index 82% rename from lib/plugins/tag/asset_path.js rename to lib/plugins/tag/asset_path.ts index d988176d30..7242e3ce73 100644 --- a/lib/plugins/tag/asset_path.js +++ b/lib/plugins/tag/asset_path.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { encodeURL } = require('hexo-util'); +import { encodeURL } from 'hexo-util'; /** * Asset path tag @@ -8,7 +6,7 @@ const { encodeURL } = require('hexo-util'); * Syntax: * {% asset_path slug %} */ -module.exports = ctx => { +export = ctx => { const PostAsset = ctx.model('PostAsset'); return function assetPathTag(args) { diff --git a/lib/plugins/tag/blockquote.js b/lib/plugins/tag/blockquote.ts similarity index 93% rename from lib/plugins/tag/blockquote.js rename to lib/plugins/tag/blockquote.ts index 847727da92..1f99e67c1a 100644 --- a/lib/plugins/tag/blockquote.js +++ b/lib/plugins/tag/blockquote.ts @@ -1,8 +1,6 @@ -'use strict'; - // Based on: https://raw.github.com/imathis/octopress/master/plugins/blockquote.rb -const titlecase = require('titlecase'); +import titlecase from 'titlecase'; const rFullCiteWithTitle = /(\S.*)\s+(https?:\/\/\S+)\s+(.+)/i; const rFullCite = /(\S.*)\s+(https?:\/\/\S+)/i; @@ -57,7 +55,7 @@ const parseFooter = (args, ctx) => { * {% endblockquote %} */ -module.exports = ctx => function blockquoteTag(args, content) { +export = ctx => function blockquoteTag(args, content) { const footer = parseFooter(args, ctx); let result = '
'; diff --git a/lib/plugins/tag/code.js b/lib/plugins/tag/code.ts similarity index 92% rename from lib/plugins/tag/code.js rename to lib/plugins/tag/code.ts index d4620dcccc..266bda70e2 100644 --- a/lib/plugins/tag/code.js +++ b/lib/plugins/tag/code.ts @@ -1,13 +1,23 @@ -'use strict'; - // Based on: https://raw.github.com/imathis/octopress/master/plugins/code_block.rb -const { escapeHTML } = require('hexo-util'); +import { escapeHTML } from 'hexo-util'; const rCaptionUrlTitle = /(\S[\S\s]*)\s+(https?:\/\/\S+)\s+(.+)/i; const rCaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/\S+)/i; const rCaption = /\S[\S\s]*/; +interface Options { + lang: string; + language_attr: boolean; + firstLine: number; + caption: string; + line_number: boolean; + line_threshold: number; + mark: number[]; + wrap: boolean; + lines_length?: number; +} + /** * Code block tag * Syntax: @@ -27,7 +37,7 @@ const rCaption = /\S[\S\s]*/; * @returns {String} Code snippet with code highlighting */ -function parseArgs(args) { +function parseArgs(args): Options { const _else = []; const len = args.length; let lang, language_attr, @@ -116,7 +126,7 @@ function parseArgs(args) { }; } -module.exports = ctx => function codeTag(args, content) { +export = ctx => function codeTag(args, content) { // If neither highlight.js nor prism.js is enabled, return escaped code directly if (!ctx.extend.highlight.query(ctx.config.syntax_highlighter)) { diff --git a/lib/plugins/tag/iframe.js b/lib/plugins/tag/iframe.ts similarity index 83% rename from lib/plugins/tag/iframe.js rename to lib/plugins/tag/iframe.ts index ec8b7875f9..f1e6b2663d 100644 --- a/lib/plugins/tag/iframe.js +++ b/lib/plugins/tag/iframe.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { htmlTag } = require('hexo-util'); +import { htmlTag } from 'hexo-util'; /** * Iframe tag @@ -26,4 +24,4 @@ function iframeTag(args) { return htmlTag('iframe', attrs, ''); } -module.exports = iframeTag; +export = iframeTag; diff --git a/lib/plugins/tag/img.js b/lib/plugins/tag/img.ts similarity index 94% rename from lib/plugins/tag/img.js rename to lib/plugins/tag/img.ts index e474d27b32..22e4970020 100644 --- a/lib/plugins/tag/img.js +++ b/lib/plugins/tag/img.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { htmlTag, url_for } = require('hexo-util'); +import { htmlTag, url_for } from 'hexo-util'; const rUrl = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[.!/\\w]*))?)/; const rMetaDoubleQuote = /"?([^"]+)?"?/; @@ -12,7 +10,7 @@ const rMetaSingleQuote = /'?([^']+)?'?/; * Syntax: * {% img [class names] /path/to/image [width] [height] [title text [alt text]] %} */ -module.exports = ctx => { +export = ctx => { return function imgTag(args) { const classes = []; diff --git a/lib/plugins/tag/include_code.js b/lib/plugins/tag/include_code.ts similarity index 89% rename from lib/plugins/tag/include_code.js rename to lib/plugins/tag/include_code.ts index 8d9d1a9a95..8457c75294 100644 --- a/lib/plugins/tag/include_code.js +++ b/lib/plugins/tag/include_code.ts @@ -1,7 +1,5 @@ -'use strict'; - -const { exists, readFile } = require('hexo-fs'); -const { basename, extname, join, posix } = require('path'); +import { exists, readFile } from 'hexo-fs'; +import { basename, extname, join, posix } from 'path'; const rCaptionTitleFile = /(.*)?(?:\s+|^)(\/*\S+)/; const rLang = /\s*lang:(\w+)/i; @@ -15,7 +13,7 @@ const rTo = /\s*to:(\d+)/i; * {% include_code [title] [lang:language] path/to/file %} */ -module.exports = ctx => function includeCodeTag(args) { +export = ctx => function includeCodeTag(args) { let codeDir = ctx.config.code_dir; let arg = args.join(' '); @@ -56,7 +54,7 @@ module.exports = ctx => function includeCodeTag(args) { return exists(src).then(exist => { if (exist) return readFile(src); - }).then(code => { + }).then((code: string) => { if (!code) return; const lines = code.split('\n'); diff --git a/lib/plugins/tag/index.js b/lib/plugins/tag/index.ts similarity index 90% rename from lib/plugins/tag/index.js rename to lib/plugins/tag/index.ts index 4b6aa2531f..a136ead63f 100644 --- a/lib/plugins/tag/index.js +++ b/lib/plugins/tag/index.ts @@ -1,8 +1,6 @@ -'use strict'; +import moize from 'moize'; -const { default: moize } = require('moize'); - -module.exports = ctx => { +export default ctx => { const { tag } = ctx.extend; const blockquote = require('./blockquote')(ctx); @@ -50,7 +48,7 @@ module.exports = ctx => { // Use WeakMap to track different ctx (in case there is any) const moized = new WeakMap(); -module.exports.postFindOneFactory = function postFindOneFactory(ctx) { +export function postFindOneFactory(ctx) { if (moized.has(ctx)) { return moized.get(ctx); } @@ -62,7 +60,7 @@ module.exports.postFindOneFactory = function postFindOneFactory(ctx) { moized.set(ctx, moizedPostFindOne); return moizedPostFindOne; -}; +} function createPostFindOne(ctx) { const Post = ctx.model('Post'); diff --git a/lib/plugins/tag/link.js b/lib/plugins/tag/link.ts similarity index 92% rename from lib/plugins/tag/link.js rename to lib/plugins/tag/link.ts index 744f874f88..0df202b574 100644 --- a/lib/plugins/tag/link.js +++ b/lib/plugins/tag/link.ts @@ -1,6 +1,4 @@ -'use strict'; - -const { htmlTag } = require('hexo-util'); +import { htmlTag } from 'hexo-util'; const rUrl = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[.!/\\w]*))?)/; @@ -56,4 +54,4 @@ function linkTag(args, content) { return htmlTag('a', attrs, text.join(' ')); } -module.exports = linkTag; +export = linkTag; diff --git a/lib/plugins/tag/post_link.js b/lib/plugins/tag/post_link.ts similarity index 87% rename from lib/plugins/tag/post_link.js rename to lib/plugins/tag/post_link.ts index 838b046560..4460cef8fe 100644 --- a/lib/plugins/tag/post_link.js +++ b/lib/plugins/tag/post_link.ts @@ -1,7 +1,5 @@ -'use strict'; - -const { encodeURL, escapeHTML } = require('hexo-util'); -const { postFindOneFactory } = require('./'); +import { encodeURL, escapeHTML } from 'hexo-util'; +import { postFindOneFactory } from './'; /** * Post link tag @@ -9,7 +7,7 @@ const { postFindOneFactory } = require('./'); * Syntax: * {% post_link slug | title [title] [escape] %} */ -module.exports = ctx => { +export = ctx => { return function postLinkTag(args) { const slug = args.shift(); if (!slug) { diff --git a/lib/plugins/tag/post_path.js b/lib/plugins/tag/post_path.ts similarity index 75% rename from lib/plugins/tag/post_path.js rename to lib/plugins/tag/post_path.ts index 679f65039f..e9aec212f2 100644 --- a/lib/plugins/tag/post_path.js +++ b/lib/plugins/tag/post_path.ts @@ -1,7 +1,5 @@ -'use strict'; - -const { encodeURL } = require('hexo-util'); -const { postFindOneFactory } = require('./'); +import { encodeURL } from 'hexo-util'; +import { postFindOneFactory } from './'; /** * Post path tag @@ -9,7 +7,7 @@ const { postFindOneFactory } = require('./'); * Syntax: * {% post_path slug | title %} */ -module.exports = ctx => { +export = ctx => { return function postPathTag(args) { const slug = args.shift(); if (!slug) return; diff --git a/lib/plugins/tag/pullquote.js b/lib/plugins/tag/pullquote.ts similarity index 78% rename from lib/plugins/tag/pullquote.js rename to lib/plugins/tag/pullquote.ts index 8a2f945d4a..1235a26d9e 100644 --- a/lib/plugins/tag/pullquote.js +++ b/lib/plugins/tag/pullquote.ts @@ -1,5 +1,3 @@ -'use strict'; - /** * Pullquote tag * @@ -8,7 +6,7 @@ * Quote string * {% endpullquote %} */ -module.exports = ctx => function pullquoteTag(args, content) { +export = ctx => function pullquoteTag(args, content) { args.unshift('pullquote'); const result = ctx.render.renderSync({text: content, engine: 'markdown'}); diff --git a/lib/theme/index.js b/lib/theme/index.ts similarity index 71% rename from lib/theme/index.js rename to lib/theme/index.ts index 95f21aed4d..d37cd281b5 100644 --- a/lib/theme/index.js +++ b/lib/theme/index.ts @@ -1,12 +1,19 @@ -'use strict'; - -const { extname } = require('path'); -const Box = require('../box'); -const View = require('./view'); -const I18n = require('hexo-i18n'); +import { extname } from 'path'; +import Box from '../box'; +import View from './view'; +import I18n from 'hexo-i18n'; +import { config } from './processors/config'; +import { i18n } from './processors/i18n'; +import { source } from './processors/source'; +import { view } from './processors/view'; class Theme extends Box { - constructor(ctx, options) { + public config: any; + public views: any; + public i18n: any; + public View: any; + + constructor(ctx, options?) { super(ctx, ctx.theme_dir, options); this.config = {}; @@ -14,13 +21,13 @@ class Theme extends Box { this.views = {}; this.processors = [ - require('./processors/config'), - require('./processors/i18n'), - require('./processors/source'), - require('./processors/view') + config, + i18n, + source, + view ]; - let languages = ctx.config.language; + let languages: string | string[] = ctx.config.language; if (!Array.isArray(languages)) languages = [languages]; @@ -76,4 +83,4 @@ class Theme extends Box { } } -module.exports = Theme; +export = Theme; diff --git a/lib/theme/processors/config.js b/lib/theme/processors/config.ts similarity index 64% rename from lib/theme/processors/config.js rename to lib/theme/processors/config.ts index 53ce70ff09..64f65e2c28 100644 --- a/lib/theme/processors/config.js +++ b/lib/theme/processors/config.ts @@ -1,8 +1,6 @@ -'use strict'; +import { Pattern } from 'hexo-util'; -const { Pattern } = require('hexo-util'); - -exports.process = function(file) { +function process(file) { if (file.type === 'delete') { file.box.config = {}; return; @@ -15,6 +13,11 @@ exports.process = function(file) { this.log.error('Theme config load failed.'); throw err; }); -}; +} -exports.pattern = new Pattern(/^_config\.\w+$/); +const pattern = new Pattern(/^_config\.\w+$/); + +export const config = { + pattern, + process +}; diff --git a/lib/theme/processors/i18n.js b/lib/theme/processors/i18n.ts similarity index 64% rename from lib/theme/processors/i18n.js rename to lib/theme/processors/i18n.ts index 1fe8983671..ce955eb8a4 100644 --- a/lib/theme/processors/i18n.js +++ b/lib/theme/processors/i18n.ts @@ -1,9 +1,7 @@ -'use strict'; +import { Pattern } from 'hexo-util'; +import { extname } from 'path'; -const { Pattern } = require('hexo-util'); -const { extname } = require('path'); - -exports.process = file => { +function process(file) { const { path } = file.params; const ext = extname(path); const name = path.substring(0, path.length - ext.length); @@ -18,6 +16,11 @@ exports.process = file => { if (typeof data !== 'object') return; i18n.set(name, data); }); -}; +} -exports.pattern = new Pattern('languages/*path'); +const pattern = new Pattern('languages/*path'); + +export const i18n = { + pattern, + process +}; diff --git a/lib/theme/processors/source.js b/lib/theme/processors/source.ts similarity index 73% rename from lib/theme/processors/source.js rename to lib/theme/processors/source.ts index 826b6a109e..40915fae47 100644 --- a/lib/theme/processors/source.js +++ b/lib/theme/processors/source.ts @@ -1,9 +1,7 @@ -'use strict'; +import { Pattern } from 'hexo-util'; +import * as common from '../../plugins/processor/common'; -const { Pattern } = require('hexo-util'); -const common = require('../../plugins/processor/common'); - -exports.process = function(file) { +function process(file) { const Asset = this.model('Asset'); const id = file.source.substring(this.base_dir.length).replace(/\\/g, '/'); const { path } = file.params; @@ -22,9 +20,9 @@ exports.process = function(file) { path, modified: file.type !== 'skip' }); -}; +} -exports.pattern = new Pattern(path => { +const pattern = new Pattern(path => { if (!path.startsWith('source/')) return false; path = path.substring(7); @@ -32,3 +30,8 @@ exports.pattern = new Pattern(path => { return {path}; }); + +export const source = { + pattern, + process +}; diff --git a/lib/theme/processors/view.js b/lib/theme/processors/view.ts similarity index 56% rename from lib/theme/processors/view.js rename to lib/theme/processors/view.ts index b7cdd4a5bb..c4011564e2 100644 --- a/lib/theme/processors/view.js +++ b/lib/theme/processors/view.ts @@ -1,8 +1,6 @@ -'use strict'; +import { Pattern } from 'hexo-util'; -const { Pattern } = require('hexo-util'); - -exports.process = file => { +function process(file) { const { path } = file.params; if (file.type === 'delete') { @@ -13,6 +11,11 @@ exports.process = file => { return file.read().then(result => { file.box.setView(path, result); }); -}; +} -exports.pattern = new Pattern('layout/*path'); +const pattern = new Pattern('layout/*path'); + +export const view = { + pattern, + process +}; diff --git a/lib/theme/view.js b/lib/theme/view.ts similarity index 83% rename from lib/theme/view.js rename to lib/theme/view.ts index 6c0439bc48..f2b2234d4f 100644 --- a/lib/theme/view.js +++ b/lib/theme/view.ts @@ -1,8 +1,6 @@ -'use strict'; - -const { dirname, extname, join } = require('path'); -const { parse: yfm } = require('hexo-front-matter'); -const Promise = require('bluebird'); +import { dirname, extname, join } from 'path'; +import { parse as yfm } from 'hexo-front-matter'; +import Promise from 'bluebird'; const assignIn = (target, ...sources) => { const length = sources.length; @@ -18,7 +16,22 @@ const assignIn = (target, ...sources) => { return target; }; +class Options { + layout?: any; +} + class View { + public path: any; + public source: any; + public _theme: any; + public data: any; + public _compiled: any; + public _compiledSync: any; + public _helper: any; + public _render: any; + public layout: any; + public _content: any; + constructor(path, data) { this.path = path; this.source = join(this._theme.base, 'layout', path); @@ -27,13 +40,15 @@ class View { this._precompile(); } - render(options = {}, callback) { + // eslint-disable-next-line @typescript-eslint/ban-types + render(options: Options | Function = {}, callback) { if (!callback && typeof options === 'function') { callback = options; options = {}; } const { data } = this; - const { layout = options.layout } = data; + // eslint-disable-next-line no-extra-parens + const { layout = (options as Options).layout } = data; const locals = this._buildLocals(options); return this._compiled(this._bindHelpers(locals)).then(result => { @@ -52,7 +67,7 @@ class View { }).asCallback(callback); } - renderSync(options = {}) { + renderSync(options: Options = {}) { const { data } = this; const { layout = options.layout } = data; const locals = this._buildLocals(options); @@ -143,4 +158,4 @@ class View { } } -module.exports = View; +export = View; diff --git a/package.json b/package.json index c8fc3c53da..f432d1f283 100644 --- a/package.json +++ b/package.json @@ -2,22 +2,22 @@ "name": "hexo", "version": "6.3.0", "description": "A fast, simple & powerful blog framework, powered by Node.js.", - "main": "lib/hexo", + "main": "dist/hexo", "bin": { "hexo": "./bin/hexo" }, "scripts": { - "eslint": "eslint .", - "test": "mocha test/index.js", + "prepublish ": "npm run clean && npm run build", + "build": "tsc -b", + "clean": "tsc -b --clean", + "eslint": "eslint lib test", + "pretest": "npm run clean && npm run build", + "test": "mocha test/index.js --require ts-node/register", "test-cov": "c8 --reporter=lcovonly npm test -- --no-parallel", "prepare": "husky install" }, - "directories": { - "lib": "./lib", - "bin": "./bin" - }, "files": [ - "lib/", + "dist/", "bin/" ], "repository": "hexojs/hexo", @@ -44,7 +44,7 @@ "bluebird": "^3.7.2", "hexo-cli": "^4.3.0", "hexo-front-matter": "^4.0.0", - "hexo-fs": "^4.0.0", + "hexo-fs": "^4.1.1", "hexo-i18n": "^2.0.0", "hexo-log": "^4.0.1", "hexo-util": "^3.0.1", @@ -66,6 +66,10 @@ }, "devDependencies": { "@easyops/git-exec-and-restage": "^1.0.4", + "@types/bluebird": "^3.5.37", + "@types/node": "^18.11.8", + "@typescript-eslint/eslint-plugin": "^5.41.0", + "@typescript-eslint/parser": "^5.41.0", "0x": "^5.1.2", "c8": "^7.12.0", "chai": "^4.3.6", @@ -77,7 +81,9 @@ "husky": "^8.0.1", "lint-staged": "^13.0.3", "mocha": "^10.0.0", - "sinon": "^15.0.0" + "sinon": "^15.0.0", + "ts-node": "^10.9.1", + "typescript": "^4.8.4" }, "engines": { "node": ">=14" diff --git a/test/.eslintrc b/test/.eslintrc index b05fbe4df3..6f2a1521e6 100644 --- a/test/.eslintrc +++ b/test/.eslintrc @@ -2,5 +2,11 @@ "extends": "hexo/test", "globals": { "should": true + }, + "rules": { + "@typescript-eslint/no-var-requires": 0, + "@typescript-eslint/no-empty-function": 0, + "@typescript-eslint/no-unused-vars": 0, + "node/no-missing-require": 0 } } diff --git a/test/benchmark.js b/test/benchmark.js index f22a830605..e377b140b6 100644 --- a/test/benchmark.js +++ b/test/benchmark.js @@ -5,7 +5,7 @@ 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 { resolve } = require('path'); const log = require('hexo-log').default(); const { red } = require('picocolors'); const hooks = [ @@ -22,9 +22,7 @@ const isWin32 = require('os').platform() === 'win32'; const npmScript = isWin32 ? 'npm.cmd' : 'npm'; const testDir = resolve('.tmp-hexo-theme-unit-test'); -const zeroEksDir = process.env.TRAVIS_BUILD_DIR - ? join(process.env.TRAVIS_BUILD_DIR, '0x') - : resolve(testDir, '0x'); +const zeroEksDir = resolve(testDir, '0x'); const hexoBin = resolve(testDir, 'node_modules/.bin/hexo'); const isGitHubActions = process.env.GITHUB_ACTIONS; @@ -176,6 +174,9 @@ async function init() { if (await exists(resolve(testDir, 'node_modules'))) await rmdir(resolve(testDir, 'node_modules')); await spawnAsync(npmScript, ['install', '--silent'], { cwd: testDir }); + log.info('Build hexo'); + await spawnAsync(npmScript, ['run', 'build']); + log.info('Replacing hexo'); await rmdir(resolve(testDir, 'node_modules', 'hexo')); diff --git a/test/scripts/box/box.js b/test/scripts/box/box.js index 4c9d26cf21..9271a2296b 100644 --- a/test/scripts/box/box.js +++ b/test/scripts/box/box.js @@ -7,9 +7,9 @@ const { hash, Pattern } = require('hexo-util'); const { spy, match, assert: sinonAssert } = require('sinon'); describe('Box', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const baseDir = join(__dirname, 'box_tmp'); - const Box = require('../../../lib/box'); + const Box = require('../../../dist/box'); const newBox = (path, config) => { const hexo = new Hexo(baseDir, { silent: true }); diff --git a/test/scripts/box/file.js b/test/scripts/box/file.js index cf4626ebe5..e019d913cc 100644 --- a/test/scripts/box/file.js +++ b/test/scripts/box/file.js @@ -5,9 +5,9 @@ const { rmdir, stat, statSync, writeFile } = require('hexo-fs'); const { load } = require('js-yaml'); describe('File', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const Box = require('../../../lib/box'); + const Box = require('../../../dist/box'); const box = new Box(hexo, join(hexo.base_dir, 'file_test')); const { File } = box; diff --git a/test/scripts/console/clean.js b/test/scripts/console/clean.js index 8f82672890..f0efb0dcac 100644 --- a/test/scripts/console/clean.js +++ b/test/scripts/console/clean.js @@ -3,12 +3,12 @@ const { exists, mkdirs, unlink, writeFile } = require('hexo-fs'); describe('clean', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); let hexo, clean; beforeEach(() => { hexo = new Hexo(__dirname, {silent: true}); - clean = require('../../../lib/plugins/console/clean').bind(hexo); + clean = require('../../../dist/plugins/console/clean').bind(hexo); }); it('delete database', async () => { diff --git a/test/scripts/console/config.js b/test/scripts/console/config.js index 747ab6f51e..9ed935e19b 100644 --- a/test/scripts/console/config.js +++ b/test/scripts/console/config.js @@ -6,9 +6,9 @@ const { load } = require('js-yaml'); const { stub, assert: sinonAssert } = require('sinon'); describe('config', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'config_test'), {silent: true}); - const config = require('../../../lib/plugins/console/config').bind(hexo); + const config = require('../../../dist/plugins/console/config').bind(hexo); before(async () => { await mkdirs(hexo.base_dir); diff --git a/test/scripts/console/deploy.js b/test/scripts/console/deploy.js index 457e4c3305..86e0c16675 100644 --- a/test/scripts/console/deploy.js +++ b/test/scripts/console/deploy.js @@ -5,9 +5,9 @@ const { join } = require('path'); const { spy, stub, assert: sinonAssert } = require('sinon'); describe('deploy', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'deploy_test'), { silent: true }); - const deploy = require('../../../lib/plugins/console/deploy').bind(hexo); + const deploy = require('../../../dist/plugins/console/deploy').bind(hexo); before(async () => { await mkdirs(hexo.public_dir); @@ -97,7 +97,7 @@ describe('deploy', () => { const hexo = new Hexo(join(__dirname, 'deploy_test')); hexo.log.error = logSpy; - const deploy = require('../../../lib/plugins/console/deploy').bind(hexo); + const deploy = require('../../../dist/plugins/console/deploy').bind(hexo); hexo.extend.deployer.register('baz', () => { }); hexo.config.deploy = { diff --git a/test/scripts/console/generate.js b/test/scripts/console/generate.js index 68c8efaaaa..7ac2bae2d4 100644 --- a/test/scripts/console/generate.js +++ b/test/scripts/console/generate.js @@ -6,8 +6,8 @@ const Promise = require('bluebird'); const { spy } = require('sinon'); describe('generate', () => { - const Hexo = require('../../../lib/hexo'); - const generateConsole = require('../../../lib/plugins/console/generate'); + const Hexo = require('../../../dist/hexo'); + const generateConsole = require('../../../dist/plugins/console/generate'); let hexo, generate; beforeEach(async () => { @@ -290,8 +290,8 @@ describe('generate', () => { // #3975 workaround for Windows describe('generate - watch (delete)', () => { - const Hexo = require('../../../lib/hexo'); - const generateConsole = require('../../../lib/plugins/console/generate'); + const Hexo = require('../../../dist/hexo'); + const generateConsole = require('../../../dist/plugins/console/generate'); const hexo = new Hexo(join(__dirname, 'generate_test'), {silent: true}); const generate = generateConsole.bind(hexo); diff --git a/test/scripts/console/list.js b/test/scripts/console/list.js index 61c3ca2fa2..530a83ffbd 100644 --- a/test/scripts/console/list.js +++ b/test/scripts/console/list.js @@ -3,13 +3,13 @@ const { spy } = require('sinon'); describe('Console list', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); it('no args', () => { hexo.call = spy(); - const list = require('../../../lib/plugins/console/list').bind(hexo); + const list = require('../../../dist/plugins/console/list').bind(hexo); list({ _: [''] }); @@ -21,7 +21,7 @@ describe('Console list', () => { it('list type not found', () => { hexo.call = spy(); - const list = require('../../../lib/plugins/console/list').bind(hexo); + const list = require('../../../dist/plugins/console/list').bind(hexo); list({ _: ['test'] }); diff --git a/test/scripts/console/list_categories.js b/test/scripts/console/list_categories.js index e46324a396..5a67aa93be 100644 --- a/test/scripts/console/list_categories.js +++ b/test/scripts/console/list_categories.js @@ -4,11 +4,11 @@ const Promise = require('bluebird'); const { stub, assert: sinonAssert } = require('sinon'); describe('Console list', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const Post = hexo.model('Post'); - const listCategories = require('../../../lib/plugins/console/list/category').bind(hexo); + const listCategories = require('../../../dist/plugins/console/list/category').bind(hexo); let logStub; diff --git a/test/scripts/console/list_page.js b/test/scripts/console/list_page.js index d0bb19c4e1..080a6993b6 100644 --- a/test/scripts/console/list_page.js +++ b/test/scripts/console/list_page.js @@ -3,10 +3,10 @@ const { stub, assert: sinonAssert } = require('sinon'); describe('Console list', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); const Page = hexo.model('Page'); - const listPages = require('../../../lib/plugins/console/list/page').bind(hexo); + const listPages = require('../../../dist/plugins/console/list/page').bind(hexo); hexo.config.permalink = ':title/'; diff --git a/test/scripts/console/list_post.js b/test/scripts/console/list_post.js index a57e5d538a..23376a2bcc 100644 --- a/test/scripts/console/list_post.js +++ b/test/scripts/console/list_post.js @@ -3,11 +3,11 @@ const { stub, assert: sinonAssert } = require('sinon'); describe('Console list', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const Post = hexo.model('Post'); - const listPosts = require('../../../lib/plugins/console/list/post').bind(hexo); + const listPosts = require('../../../dist/plugins/console/list/post').bind(hexo); let logStub; diff --git a/test/scripts/console/list_route.js b/test/scripts/console/list_route.js index ae3892884b..0cbf86996f 100644 --- a/test/scripts/console/list_route.js +++ b/test/scripts/console/list_route.js @@ -3,10 +3,10 @@ const { stub, assert: sinonAssert } = require('sinon'); describe('Console list', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const listRoutes = require('../../../lib/plugins/console/list/route').bind(hexo); + const listRoutes = require('../../../dist/plugins/console/list/route').bind(hexo); const { route } = hexo; let logStub; diff --git a/test/scripts/console/list_tags.js b/test/scripts/console/list_tags.js index 7dd39532cf..01073f7b14 100644 --- a/test/scripts/console/list_tags.js +++ b/test/scripts/console/list_tags.js @@ -4,11 +4,11 @@ const Promise = require('bluebird'); const { stub, assert: sinonAssert } = require('sinon'); describe('Console list', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const Post = hexo.model('Post'); - const listTags = require('../../../lib/plugins/console/list/tag').bind(hexo); + const listTags = require('../../../dist/plugins/console/list/tag').bind(hexo); hexo.config.permalink = ':title/'; diff --git a/test/scripts/console/migrate.js b/test/scripts/console/migrate.js index 2de2f77361..a277197d4e 100644 --- a/test/scripts/console/migrate.js +++ b/test/scripts/console/migrate.js @@ -3,9 +3,9 @@ const { spy, assert: sinonAssert, stub } = require('sinon'); describe('migrate', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname, { silent: true }); - const migrate = require('../../../lib/plugins/console/migrate').bind(hexo); + const migrate = require('../../../dist/plugins/console/migrate').bind(hexo); it('default', async () => { const migrator = spy(); @@ -21,7 +21,7 @@ describe('migrate', () => { it('no args', async () => { const hexo = new Hexo(__dirname, { silent: true }); hexo.call = spy(); - const migrate = require('../../../lib/plugins/console/migrate').bind(hexo); + const migrate = require('../../../dist/plugins/console/migrate').bind(hexo); await migrate({ _: [] }); hexo.call.calledOnce.should.be.true; diff --git a/test/scripts/console/new.js b/test/scripts/console/new.js index 8e64429ae0..16e93f4b69 100644 --- a/test/scripts/console/new.js +++ b/test/scripts/console/new.js @@ -7,9 +7,9 @@ const Promise = require('bluebird'); const { useFakeTimers } = require('sinon'); describe('new', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'new_test'), {silent: true}); - const n = require('../../../lib/plugins/console/new').bind(hexo); + const n = require('../../../dist/plugins/console/new').bind(hexo); const post = hexo.post; const now = Date.now(); let clock; diff --git a/test/scripts/console/publish.js b/test/scripts/console/publish.js index e96738f9eb..44069af45e 100644 --- a/test/scripts/console/publish.js +++ b/test/scripts/console/publish.js @@ -7,9 +7,9 @@ const Promise = require('bluebird'); const { useFakeTimers, spy } = require('sinon'); describe('publish', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'publish_test'), {silent: true}); - const publish = require('../../../lib/plugins/console/publish').bind(hexo); + const publish = require('../../../dist/plugins/console/publish').bind(hexo); const post = hexo.post; const now = Date.now(); let clock; @@ -73,7 +73,7 @@ describe('publish', () => { it('no args', async () => { const hexo = new Hexo(join(__dirname, 'publish_test'), {silent: true}); hexo.call = spy(); - const publish = require('../../../lib/plugins/console/publish').bind(hexo); + const publish = require('../../../dist/plugins/console/publish').bind(hexo); await publish({_: []}); diff --git a/test/scripts/console/render.js b/test/scripts/console/render.js index d30217ba1a..1a611766c8 100644 --- a/test/scripts/console/render.js +++ b/test/scripts/console/render.js @@ -6,9 +6,9 @@ const Promise = require('bluebird'); const { spy } = require('sinon'); describe('render', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'render_test'), {silent: true}); - const render = require('../../../lib/plugins/console/render').bind(hexo); + const render = require('../../../dist/plugins/console/render').bind(hexo); before(async () => { await mkdirs(hexo.base_dir); @@ -26,7 +26,7 @@ describe('render', () => { it('no args', async () => { const hexo = new Hexo(join(__dirname, 'render_test'), {silent: true}); hexo.call = spy(); - const render = require('../../../lib/plugins/console/render').bind(hexo); + const render = require('../../../dist/plugins/console/render').bind(hexo); await render({_: []}); diff --git a/test/scripts/extend/console.js b/test/scripts/extend/console.js index 2d3ba48765..479937d687 100644 --- a/test/scripts/extend/console.js +++ b/test/scripts/extend/console.js @@ -1,7 +1,7 @@ 'use strict'; describe('Console', () => { - const Console = require('../../../lib/extend/console'); + const Console = require('../../../dist/extend/console'); it('register()', () => { const c = new Console(); diff --git a/test/scripts/extend/deployer.js b/test/scripts/extend/deployer.js index ddc73193c9..7318cc9777 100644 --- a/test/scripts/extend/deployer.js +++ b/test/scripts/extend/deployer.js @@ -1,7 +1,7 @@ 'use strict'; describe('Deployer', () => { - const Deployer = require('../../../lib/extend/deployer'); + const Deployer = require('../../../dist/extend/deployer'); it('register()', () => { const d = new Deployer(); diff --git a/test/scripts/extend/filter.js b/test/scripts/extend/filter.js index 3f03ee74b6..6010ce5bc6 100644 --- a/test/scripts/extend/filter.js +++ b/test/scripts/extend/filter.js @@ -3,7 +3,7 @@ const { spy } = require('sinon'); describe('Filter', () => { - const Filter = require('../../../lib/extend/filter'); + const Filter = require('../../../dist/extend/filter'); it('register()', () => { const f = new Filter(); diff --git a/test/scripts/extend/generator.js b/test/scripts/extend/generator.js index 154883c579..d90b295fd1 100644 --- a/test/scripts/extend/generator.js +++ b/test/scripts/extend/generator.js @@ -1,7 +1,7 @@ 'use strict'; describe('Generator', () => { - const Generator = require('../../../lib/extend/generator'); + const Generator = require('../../../dist/extend/generator'); it('register()', () => { const g = new Generator(); diff --git a/test/scripts/extend/helper.js b/test/scripts/extend/helper.js index fd5078313d..30054f1a4b 100644 --- a/test/scripts/extend/helper.js +++ b/test/scripts/extend/helper.js @@ -1,7 +1,7 @@ 'use strict'; describe('Helper', () => { - const Helper = require('../../../lib/extend/helper'); + const Helper = require('../../../dist/extend/helper'); it('register()', () => { const h = new Helper(); diff --git a/test/scripts/extend/injector.js b/test/scripts/extend/injector.js index 08ffc8110c..d82c035607 100644 --- a/test/scripts/extend/injector.js +++ b/test/scripts/extend/injector.js @@ -13,7 +13,7 @@ describe('Injector', () => { '' ].join(''); - const Injector = require('../../../lib/extend/injector'); + const Injector = require('../../../dist/extend/injector'); it('register() - entry is required', () => { const i = new Injector(); diff --git a/test/scripts/extend/migrator.js b/test/scripts/extend/migrator.js index 8668c3e94e..fe045b3c28 100644 --- a/test/scripts/extend/migrator.js +++ b/test/scripts/extend/migrator.js @@ -1,7 +1,7 @@ 'use strict'; describe('Migrator', () => { - const Migrator = require('../../../lib/extend/migrator'); + const Migrator = require('../../../dist/extend/migrator'); it('register()', () => { const d = new Migrator(); diff --git a/test/scripts/extend/processor.js b/test/scripts/extend/processor.js index 00894de7f0..eddae6d80b 100644 --- a/test/scripts/extend/processor.js +++ b/test/scripts/extend/processor.js @@ -1,7 +1,7 @@ 'use strict'; describe('Processor', () => { - const Processor = require('../../../lib/extend/processor'); + const Processor = require('../../../dist/extend/processor'); it('register()', () => { const p = new Processor(); diff --git a/test/scripts/extend/renderer.js b/test/scripts/extend/renderer.js index be09798410..44327d0cb7 100644 --- a/test/scripts/extend/renderer.js +++ b/test/scripts/extend/renderer.js @@ -1,7 +1,7 @@ 'use strict'; describe('Renderer', () => { - const Renderer = require('../../../lib/extend/renderer'); + const Renderer = require('../../../dist/extend/renderer'); it('register()', () => { const r = new Renderer(); diff --git a/test/scripts/extend/tag.js b/test/scripts/extend/tag.js index a89f6f7c8b..e46c7a3cb2 100644 --- a/test/scripts/extend/tag.js +++ b/test/scripts/extend/tag.js @@ -3,7 +3,7 @@ const { spy } = require('sinon'); describe('Tag', () => { - const Tag = require('../../../lib/extend/tag'); + const Tag = require('../../../dist/extend/tag'); const tag = new Tag(); it('register()', async () => { diff --git a/test/scripts/extend/tag_errors.js b/test/scripts/extend/tag_errors.js index 6a674430b8..3184d8a09d 100644 --- a/test/scripts/extend/tag_errors.js +++ b/test/scripts/extend/tag_errors.js @@ -1,7 +1,7 @@ 'use strict'; describe('Tag Errors', () => { - const Tag = require('../../../lib/extend/tag'); + const Tag = require('../../../dist/extend/tag'); const assertNunjucksError = (err, line, type) => { err.should.have.property('name', 'Nunjucks Error'); diff --git a/test/scripts/filters/backtick_code_block.js b/test/scripts/filters/backtick_code_block.js index 4b0d75e31b..4b7c932f52 100644 --- a/test/scripts/filters/backtick_code_block.js +++ b/test/scripts/filters/backtick_code_block.js @@ -1,13 +1,13 @@ 'use strict'; const util = require('hexo-util'); -const defaultConfig = require('../../../lib/hexo/default_config'); +const defaultConfig = require('../../../dist/hexo/default_config'); describe('Backtick code block', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - require('../../../lib/plugins/highlight/')(hexo); - const codeBlock = require('../../../lib/plugins/filter/before_post_render/backtick_code_block')(hexo); + require('../../../dist/plugins/highlight/')(hexo); + const codeBlock = require('../../../dist/plugins/filter/before_post_render/backtick_code_block')(hexo); const code = [ 'if (tired && night) {', diff --git a/test/scripts/filters/excerpt.js b/test/scripts/filters/excerpt.js index eb485221f5..c45bd7f757 100644 --- a/test/scripts/filters/excerpt.js +++ b/test/scripts/filters/excerpt.js @@ -1,9 +1,9 @@ 'use strict'; describe('Excerpt', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - const excerpt = require('../../../lib/plugins/filter/after_post_render/excerpt').bind(hexo); + const excerpt = require('../../../dist/plugins/filter/after_post_render/excerpt').bind(hexo); it('without ', () => { const content = [ diff --git a/test/scripts/filters/external_link.js b/test/scripts/filters/external_link.js index 46b4ade372..dbec1dbca5 100644 --- a/test/scripts/filters/external_link.js +++ b/test/scripts/filters/external_link.js @@ -3,13 +3,13 @@ const decache = require('decache'); describe('External link', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); let externalLink; beforeEach(() => { - decache('../../../lib/plugins/filter/after_render/external_link'); - externalLink = require('../../../lib/plugins/filter/after_render/external_link').bind(hexo); + decache('../../../dist/plugins/filter/after_render/external_link'); + externalLink = require('../../../dist/plugins/filter/after_render/external_link').bind(hexo); }); hexo.config = { @@ -137,14 +137,14 @@ describe('External link', () => { }); describe('External link - post', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); let externalLink; beforeEach(() => { - decache('../../../lib/plugins/filter/after_post_render/external_link'); - externalLink = require('../../../lib/plugins/filter/after_post_render/external_link').bind(hexo); + decache('../../../dist/plugins/filter/after_post_render/external_link'); + externalLink = require('../../../dist/plugins/filter/after_post_render/external_link').bind(hexo); }); hexo.config = { diff --git a/test/scripts/filters/i18n_locals.js b/test/scripts/filters/i18n_locals.js index 75fe3ed9f0..6ac2f920dc 100644 --- a/test/scripts/filters/i18n_locals.js +++ b/test/scripts/filters/i18n_locals.js @@ -1,9 +1,9 @@ 'use strict'; describe('i18n locals', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - const i18nFilter = require('../../../lib/plugins/filter/template_locals/i18n').bind(hexo); + const i18nFilter = require('../../../dist/plugins/filter/template_locals/i18n').bind(hexo); const theme = hexo.theme; const i18n = theme.i18n; diff --git a/test/scripts/filters/meta_generator.js b/test/scripts/filters/meta_generator.js index 7d6078cedf..f87bcc000b 100644 --- a/test/scripts/filters/meta_generator.js +++ b/test/scripts/filters/meta_generator.js @@ -3,14 +3,14 @@ const decache = require('decache'); describe('Meta Generator', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); let metaGenerator; const cheerio = require('cheerio'); beforeEach(() => { - decache('../../../lib/plugins/filter/after_render/meta_generator'); - metaGenerator = require('../../../lib/plugins/filter/after_render/meta_generator').bind(hexo); + decache('../../../dist/plugins/filter/after_render/meta_generator'); + metaGenerator = require('../../../dist/plugins/filter/after_render/meta_generator').bind(hexo); }); it('default', () => { diff --git a/test/scripts/filters/new_post_path.js b/test/scripts/filters/new_post_path.js index c5e2f528e9..006c973538 100644 --- a/test/scripts/filters/new_post_path.js +++ b/test/scripts/filters/new_post_path.js @@ -6,9 +6,9 @@ const { createSha1Hash } = require('hexo-util'); const { mkdirs, rmdir, unlink, writeFile } = require('hexo-fs'); describe('new_post_path', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'new_post_path_test')); - const newPostPath = require('../../../lib/plugins/filter/new_post_path').bind(hexo); + const newPostPath = require('../../../dist/plugins/filter/new_post_path').bind(hexo); const sourceDir = hexo.source_dir; const draftDir = join(sourceDir, '_drafts'); const postDir = join(sourceDir, '_posts'); diff --git a/test/scripts/filters/post_permalink.js b/test/scripts/filters/post_permalink.js index 0098edf065..e01f22a1be 100644 --- a/test/scripts/filters/post_permalink.js +++ b/test/scripts/filters/post_permalink.js @@ -3,9 +3,9 @@ const moment = require('moment'); describe('post_permalink', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - const postPermalink = require('../../../lib/plugins/filter/post_permalink').bind(hexo); + const postPermalink = require('../../../dist/plugins/filter/post_permalink').bind(hexo); const Post = hexo.model('Post'); let post; diff --git a/test/scripts/filters/render_post.js b/test/scripts/filters/render_post.js index b74074c831..ab82f405b3 100644 --- a/test/scripts/filters/render_post.js +++ b/test/scripts/filters/render_post.js @@ -3,11 +3,11 @@ const { content, expected } = require('../../fixtures/post_render'); describe('Render post', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); const Post = hexo.model('Post'); const Page = hexo.model('Page'); - const renderPost = require('../../../lib/plugins/filter/before_generate/render_post').bind(hexo); + const renderPost = require('../../../dist/plugins/filter/before_generate/render_post').bind(hexo); before(async () => { await hexo.init(); diff --git a/test/scripts/filters/save_database.js b/test/scripts/filters/save_database.js index d6a38368c4..f479cdc411 100644 --- a/test/scripts/filters/save_database.js +++ b/test/scripts/filters/save_database.js @@ -4,9 +4,9 @@ const { exists, unlink } = require('hexo-fs'); const Promise = require('bluebird'); describe('Save database', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - const saveDatabase = Promise.method(require('../../../lib/plugins/filter/before_exit/save_database')).bind(hexo); + const saveDatabase = Promise.method(require('../../../dist/plugins/filter/before_exit/save_database')).bind(hexo); const dbPath = hexo.database.options.path; it('default', async () => { diff --git a/test/scripts/filters/titlecase.js b/test/scripts/filters/titlecase.js index 126b2a156e..10b979c326 100644 --- a/test/scripts/filters/titlecase.js +++ b/test/scripts/filters/titlecase.js @@ -1,9 +1,9 @@ 'use strict'; describe('Titlecase', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - const titlecase = require('../../../lib/plugins/filter/before_post_render/titlecase').bind(hexo); + const titlecase = require('../../../dist/plugins/filter/before_post_render/titlecase').bind(hexo); it('disabled', () => { const title = 'Today is a good day'; diff --git a/test/scripts/generators/asset.js b/test/scripts/generators/asset.js index 43ad30ce67..0486dc0305 100644 --- a/test/scripts/generators/asset.js +++ b/test/scripts/generators/asset.js @@ -5,9 +5,9 @@ const { mkdirs, rmdir, unlink, writeFile } = require('hexo-fs'); const testUtil = require('../../util'); describe('asset', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'asset_test'), {silent: true}); - const generator = require('../../../lib/plugins/generator/asset').bind(hexo); + const generator = require('../../../dist/plugins/generator/asset').bind(hexo); const Asset = hexo.model('Asset'); const checkStream = async (stream, expected) => { diff --git a/test/scripts/generators/page.js b/test/scripts/generators/page.js index 2371566fad..cf0290c640 100644 --- a/test/scripts/generators/page.js +++ b/test/scripts/generators/page.js @@ -3,10 +3,10 @@ const Promise = require('bluebird'); describe('page', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname, {silent: true}); const Page = hexo.model('Page'); - const generator = Promise.method(require('../../../lib/plugins/generator/page').bind(hexo)); + const generator = Promise.method(require('../../../dist/plugins/generator/page').bind(hexo)); const locals = () => { hexo.locals.invalidate(); diff --git a/test/scripts/generators/post.js b/test/scripts/generators/post.js index 7132678015..ace0d2e859 100644 --- a/test/scripts/generators/post.js +++ b/test/scripts/generators/post.js @@ -3,10 +3,10 @@ const Promise = require('bluebird'); describe('post', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname, {silent: true}); const Post = hexo.model('Post'); - const generator = Promise.method(require('../../../lib/plugins/generator/post').bind(hexo)); + const generator = Promise.method(require('../../../dist/plugins/generator/post').bind(hexo)); hexo.config.permalink = ':title/'; diff --git a/test/scripts/helpers/css.js b/test/scripts/helpers/css.js index 4922a1f265..ea68001273 100644 --- a/test/scripts/helpers/css.js +++ b/test/scripts/helpers/css.js @@ -3,14 +3,14 @@ const cheerio = require('cheerio'); describe('css', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const ctx = { config: hexo.config }; - const css = require('../../../lib/plugins/helper/css').bind(ctx); + const css = require('../../../dist/plugins/helper/css').bind(ctx); function assertResult(result, expected) { const $ = cheerio.load(result); diff --git a/test/scripts/helpers/date.js b/test/scripts/helpers/date.js index 1b33a8528b..80e5cfa510 100644 --- a/test/scripts/helpers/date.js +++ b/test/scripts/helpers/date.js @@ -4,9 +4,9 @@ const moment = require('moment-timezone'); const { useFakeTimers } = require('sinon'); describe('date', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - const dateHelper = require('../../../lib/plugins/helper/date'); + const dateHelper = require('../../../dist/plugins/helper/date'); let clock; before(() => { diff --git a/test/scripts/helpers/debug.js b/test/scripts/helpers/debug.js index 409616f3bd..200dc33705 100644 --- a/test/scripts/helpers/debug.js +++ b/test/scripts/helpers/debug.js @@ -3,7 +3,7 @@ const { stub } = require('sinon'); describe('debug', () => { - const debug = require('../../../lib/plugins/helper/debug'); + const debug = require('../../../dist/plugins/helper/debug'); const { inspect } = require('util'); it('inspect simple object', () => { diff --git a/test/scripts/helpers/escape_html.js b/test/scripts/helpers/escape_html.js index 076a27285b..802a85b8b8 100644 --- a/test/scripts/helpers/escape_html.js +++ b/test/scripts/helpers/escape_html.js @@ -1,7 +1,7 @@ 'use strict'; describe('escape_html', () => { - const { escapeHTML } = require('../../../lib/plugins/helper/format'); + const { escapeHTML } = require('../../../dist/plugins/helper/format'); it('default', () => { escapeHTML('

Hello "world".

').should.eql('<p class="foo">Hello "world".</p>'); diff --git a/test/scripts/helpers/favicon_tag.js b/test/scripts/helpers/favicon_tag.js index 81c2dd7e11..2057042510 100644 --- a/test/scripts/helpers/favicon_tag.js +++ b/test/scripts/helpers/favicon_tag.js @@ -1,14 +1,14 @@ 'use strict'; describe('favicon_tag', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const ctx = { config: hexo.config }; - const favicon = require('../../../lib/plugins/helper/favicon_tag').bind(ctx); + const favicon = require('../../../dist/plugins/helper/favicon_tag').bind(ctx); it('path', () => { favicon('favicon.ico').should.eql(''); diff --git a/test/scripts/helpers/feed_tag.js b/test/scripts/helpers/feed_tag.js index 354752c856..9dd96328f5 100644 --- a/test/scripts/helpers/feed_tag.js +++ b/test/scripts/helpers/feed_tag.js @@ -12,7 +12,7 @@ describe('feed_tag', () => { beforeEach(() => { ctx.config.feed = {}; }); - const feed = require('../../../lib/plugins/helper/feed_tag').bind(ctx); + const feed = require('../../../dist/plugins/helper/feed_tag').bind(ctx); it('path - atom', () => { feed('atom.xml').should.eql(''); diff --git a/test/scripts/helpers/fragment_cache.js b/test/scripts/helpers/fragment_cache.js index 92ff914fe6..f9e391a492 100644 --- a/test/scripts/helpers/fragment_cache.js +++ b/test/scripts/helpers/fragment_cache.js @@ -1,9 +1,9 @@ 'use strict'; describe('fragment_cache', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const fragment_cache = require('../../../lib/plugins/helper/fragment_cache')(hexo); + const fragment_cache = require('../../../dist/plugins/helper/fragment_cache')(hexo); fragment_cache.call({cache: true}, 'foo', () => 123); diff --git a/test/scripts/helpers/full_url_for.js b/test/scripts/helpers/full_url_for.js index 35dc936062..313de00273 100755 --- a/test/scripts/helpers/full_url_for.js +++ b/test/scripts/helpers/full_url_for.js @@ -5,7 +5,7 @@ describe('full_url_for', () => { config: { url: 'https://example.com' } }; - const fullUrlFor = require('../../../lib/plugins/helper/full_url_for').bind(ctx); + const fullUrlFor = require('../../../dist/plugins/helper/full_url_for').bind(ctx); it('no path input', () => { fullUrlFor().should.eql(ctx.config.url + '/'); diff --git a/test/scripts/helpers/gravatar.js b/test/scripts/helpers/gravatar.js index 8b577e97af..7fd79bfdba 100644 --- a/test/scripts/helpers/gravatar.js +++ b/test/scripts/helpers/gravatar.js @@ -3,7 +3,7 @@ const crypto = require('crypto'); describe('gravatar', () => { - const gravatar = require('../../../lib/plugins/helper/gravatar'); + const gravatar = require('../../../dist/plugins/helper/gravatar'); function md5(str) { return crypto.createHash('md5').update(str).digest('hex'); diff --git a/test/scripts/helpers/image_tag.js b/test/scripts/helpers/image_tag.js index 0f7b22af4c..f8a87edbbe 100644 --- a/test/scripts/helpers/image_tag.js +++ b/test/scripts/helpers/image_tag.js @@ -1,14 +1,14 @@ 'use strict'; describe('image_tag', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const ctx = { config: hexo.config }; - const img = require('../../../lib/plugins/helper/image_tag').bind(ctx); + const img = require('../../../dist/plugins/helper/image_tag').bind(ctx); it('path', () => { img('https://hexo.io/image.jpg').should.eql(''); diff --git a/test/scripts/helpers/is.js b/test/scripts/helpers/is.js index fa8acd9551..cec0990aa9 100644 --- a/test/scripts/helpers/is.js +++ b/test/scripts/helpers/is.js @@ -1,9 +1,9 @@ 'use strict'; describe('is', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const is = require('../../../lib/plugins/helper/is'); + const is = require('../../../dist/plugins/helper/is'); it('is_current', async () => { await is.current.call({path: 'index.html', config: hexo.config}).should.be.true; diff --git a/test/scripts/helpers/js.js b/test/scripts/helpers/js.js index cee95d2c85..5dbc4a16d4 100644 --- a/test/scripts/helpers/js.js +++ b/test/scripts/helpers/js.js @@ -3,14 +3,14 @@ const cheerio = require('cheerio'); describe('js', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const ctx = { config: hexo.config }; - const js = require('../../../lib/plugins/helper/js').bind(ctx); + const js = require('../../../dist/plugins/helper/js').bind(ctx); function assertResult(result, expected) { const $ = cheerio.load(result); diff --git a/test/scripts/helpers/link_to.js b/test/scripts/helpers/link_to.js index d569eb8f30..528a0ce7b8 100644 --- a/test/scripts/helpers/link_to.js +++ b/test/scripts/helpers/link_to.js @@ -1,14 +1,14 @@ 'use strict'; describe('link_to', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const ctx = { config: hexo.config }; - const linkTo = require('../../../lib/plugins/helper/link_to').bind(ctx); + const linkTo = require('../../../dist/plugins/helper/link_to').bind(ctx); it('path', () => { linkTo('https://hexo.io/').should.eql('hexo.io'); diff --git a/test/scripts/helpers/list_archives.js b/test/scripts/helpers/list_archives.js index 468b498b04..b733a60c6c 100644 --- a/test/scripts/helpers/list_archives.js +++ b/test/scripts/helpers/list_archives.js @@ -1,7 +1,7 @@ 'use strict'; describe('list_archives', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const Post = hexo.model('Post'); @@ -10,7 +10,7 @@ describe('list_archives', () => { page: {} }; - const listArchives = require('../../../lib/plugins/helper/list_archives').bind(ctx); + const listArchives = require('../../../dist/plugins/helper/list_archives').bind(ctx); function resetLocals() { hexo.locals.invalidate(); diff --git a/test/scripts/helpers/list_categories.js b/test/scripts/helpers/list_categories.js index a8c1120112..5cdb46e01f 100644 --- a/test/scripts/helpers/list_categories.js +++ b/test/scripts/helpers/list_categories.js @@ -1,7 +1,7 @@ 'use strict'; describe('list_categories', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const Post = hexo.model('Post'); const Category = hexo.model('Category'); @@ -10,7 +10,7 @@ describe('list_categories', () => { config: hexo.config }; - const listCategories = require('../../../lib/plugins/helper/list_categories').bind(ctx); + const listCategories = require('../../../dist/plugins/helper/list_categories').bind(ctx); before(async () => { await hexo.init(); diff --git a/test/scripts/helpers/list_posts.js b/test/scripts/helpers/list_posts.js index 88cd6c4be7..dbb6810331 100644 --- a/test/scripts/helpers/list_posts.js +++ b/test/scripts/helpers/list_posts.js @@ -1,7 +1,7 @@ 'use strict'; describe('list_posts', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const Post = hexo.model('Post'); @@ -9,7 +9,7 @@ describe('list_posts', () => { config: hexo.config }; - const listPosts = require('../../../lib/plugins/helper/list_posts').bind(ctx); + const listPosts = require('../../../dist/plugins/helper/list_posts').bind(ctx); hexo.config.permalink = ':title/'; diff --git a/test/scripts/helpers/list_tags.js b/test/scripts/helpers/list_tags.js index 7e07280fb7..c5e196cc91 100644 --- a/test/scripts/helpers/list_tags.js +++ b/test/scripts/helpers/list_tags.js @@ -1,7 +1,7 @@ 'use strict'; describe('list_tags', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const Post = hexo.model('Post'); const Tag = hexo.model('Tag'); @@ -10,7 +10,7 @@ describe('list_tags', () => { config: hexo.config }; - const listTags = require('../../../lib/plugins/helper/list_tags').bind(ctx); + const listTags = require('../../../dist/plugins/helper/list_tags').bind(ctx); before(async () => { await hexo.init(); @@ -207,7 +207,7 @@ describe('list_tags', () => { }); describe('list_tags transform', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const Post = hexo.model('Post'); @@ -215,7 +215,7 @@ describe('list_tags transform', () => { config: hexo.config }; - const listTags = require('../../../lib/plugins/helper/list_tags').bind(ctx); + const listTags = require('../../../dist/plugins/helper/list_tags').bind(ctx); before(async () => { await hexo.init(); diff --git a/test/scripts/helpers/mail_to.js b/test/scripts/helpers/mail_to.js index bcac9970c7..8dc09ded62 100644 --- a/test/scripts/helpers/mail_to.js +++ b/test/scripts/helpers/mail_to.js @@ -1,14 +1,14 @@ 'use strict'; describe('mail_to', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const ctx = { config: hexo.config }; - const mailto = require('../../../lib/plugins/helper/mail_to').bind(ctx); + const mailto = require('../../../dist/plugins/helper/mail_to').bind(ctx); it('path', () => { mailto('abc@example.com').should.eql('abc@example.com'); diff --git a/test/scripts/helpers/markdown.js b/test/scripts/helpers/markdown.js index 524c64b7fe..5fd2cd6c38 100644 --- a/test/scripts/helpers/markdown.js +++ b/test/scripts/helpers/markdown.js @@ -1,14 +1,14 @@ 'use strict'; describe('markdown', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const ctx = { - render: require('../../../lib/plugins/helper/render')(hexo) + render: require('../../../dist/plugins/helper/render')(hexo) }; - const markdown = require('../../../lib/plugins/helper/markdown').bind(ctx); + const markdown = require('../../../dist/plugins/helper/markdown').bind(ctx); before(() => hexo.init().then(() => hexo.loadPlugin(require.resolve('hexo-renderer-marked')))); diff --git a/test/scripts/helpers/meta_generator.js b/test/scripts/helpers/meta_generator.js index c5a180d6f1..972820453e 100755 --- a/test/scripts/helpers/meta_generator.js +++ b/test/scripts/helpers/meta_generator.js @@ -1,10 +1,10 @@ 'use strict'; describe('meta_generator', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - const metaGeneratorHelper = require('../../../lib/plugins/helper/meta_generator').bind(hexo); + const metaGeneratorHelper = require('../../../dist/plugins/helper/meta_generator').bind(hexo); it('default', () => { const { version } = hexo; diff --git a/test/scripts/helpers/number_format.js b/test/scripts/helpers/number_format.js index c47c819e62..32390637a5 100644 --- a/test/scripts/helpers/number_format.js +++ b/test/scripts/helpers/number_format.js @@ -1,7 +1,7 @@ 'use strict'; describe('number_format', () => { - const numberFormat = require('../../../lib/plugins/helper/number_format'); + const numberFormat = require('../../../dist/plugins/helper/number_format'); it('default', () => { numberFormat(1234.567).should.eql('1,234.567'); diff --git a/test/scripts/helpers/open_graph.js b/test/scripts/helpers/open_graph.js index ba78dc3bd3..433cddbe24 100644 --- a/test/scripts/helpers/open_graph.js +++ b/test/scripts/helpers/open_graph.js @@ -3,13 +3,13 @@ const moment = require('moment'); const cheerio = require('cheerio'); const { encodeURL } = require('hexo-util'); -const defaultConfig = require('../../../lib/hexo/default_config'); +const defaultConfig = require('../../../dist/hexo/default_config'); describe('open_graph', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - const openGraph = require('../../../lib/plugins/helper/open_graph'); - const isPost = require('../../../lib/plugins/helper/is').post; + const openGraph = require('../../../dist/plugins/helper/open_graph'); + const isPost = require('../../../dist/plugins/helper/is').post; const tag = require('hexo-util').htmlTag; const Post = hexo.model('Post'); diff --git a/test/scripts/helpers/paginator.js b/test/scripts/helpers/paginator.js index f1aeb63390..04826e453b 100644 --- a/test/scripts/helpers/paginator.js +++ b/test/scripts/helpers/paginator.js @@ -3,7 +3,7 @@ const { url_for } = require('hexo-util'); describe('paginator', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const ctx = { @@ -15,7 +15,7 @@ describe('paginator', () => { config: hexo.config }; - const paginator = require('../../../lib/plugins/helper/paginator').bind(ctx); + const paginator = require('../../../dist/plugins/helper/paginator').bind(ctx); function link(i) { return url_for.call(ctx, i === 1 ? '' : 'page/' + i + '/'); diff --git a/test/scripts/helpers/partial.js b/test/scripts/helpers/partial.js index 0f7a1015dd..ca4b2133d4 100644 --- a/test/scripts/helpers/partial.js +++ b/test/scripts/helpers/partial.js @@ -5,7 +5,7 @@ const fs = require('hexo-fs'); const Promise = require('bluebird'); describe('partial', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(pathFn.join(__dirname, 'partial_test'), {silent: true}); const themeDir = pathFn.join(hexo.base_dir, 'themes', 'test'); const viewDir = pathFn.join(themeDir, 'layout') + pathFn.sep; @@ -20,11 +20,11 @@ describe('partial', () => { cache: true }; - ctx.fragment_cache = require('../../../lib/plugins/helper/fragment_cache')(hexo); + ctx.fragment_cache = require('../../../dist/plugins/helper/fragment_cache')(hexo); hexo.env.init = true; - const partial = require('../../../lib/plugins/helper/partial')(hexo).bind(ctx); + const partial = require('../../../dist/plugins/helper/partial')(hexo).bind(ctx); before(async () => { await Promise.all([ diff --git a/test/scripts/helpers/relative_url.js b/test/scripts/helpers/relative_url.js index 60930788bc..f9f691f602 100644 --- a/test/scripts/helpers/relative_url.js +++ b/test/scripts/helpers/relative_url.js @@ -1,7 +1,7 @@ 'use strict'; describe('relative_url', () => { - const relativeURL = require('../../../lib/plugins/helper/relative_url'); + const relativeURL = require('../../../dist/plugins/helper/relative_url'); it('from root', () => { relativeURL('', 'css/style.css').should.eql('css/style.css'); diff --git a/test/scripts/helpers/render.js b/test/scripts/helpers/render.js index 568af34c0f..04b8c9cc62 100644 --- a/test/scripts/helpers/render.js +++ b/test/scripts/helpers/render.js @@ -1,9 +1,9 @@ 'use strict'; describe('render', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const render = require('../../../lib/plugins/helper/render')(hexo); + const render = require('../../../dist/plugins/helper/render')(hexo); before(() => hexo.init()); diff --git a/test/scripts/helpers/search_form.js b/test/scripts/helpers/search_form.js index 685dbe3eef..6f086008e4 100644 --- a/test/scripts/helpers/search_form.js +++ b/test/scripts/helpers/search_form.js @@ -1,7 +1,7 @@ 'use strict'; describe('search_form', () => { - const searchForm = require('../../../lib/plugins/helper/search_form').bind({ + const searchForm = require('../../../dist/plugins/helper/search_form').bind({ config: {url: 'https://hexo.io'} }); diff --git a/test/scripts/helpers/tagcloud.js b/test/scripts/helpers/tagcloud.js index dba089a256..47ffe87e51 100644 --- a/test/scripts/helpers/tagcloud.js +++ b/test/scripts/helpers/tagcloud.js @@ -3,7 +3,7 @@ const Promise = require('bluebird'); describe('tagcloud', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const Post = hexo.model('Post'); const Tag = hexo.model('Tag'); @@ -12,7 +12,7 @@ describe('tagcloud', () => { config: hexo.config }; - const tagcloud = require('../../../lib/plugins/helper/tagcloud').bind(ctx); + const tagcloud = require('../../../dist/plugins/helper/tagcloud').bind(ctx); before(async () => { await hexo.init(); @@ -50,7 +50,7 @@ describe('tagcloud', () => { await hexo.init(); hexo.locals.invalidate(); hexo.site = hexo.locals.toObject(); - const tagcloud = require('../../../lib/plugins/helper/tagcloud').bind(hexo); + const tagcloud = require('../../../dist/plugins/helper/tagcloud').bind(hexo); const result = tagcloud(); diff --git a/test/scripts/helpers/toc.js b/test/scripts/helpers/toc.js index 47f0014790..b93d7e1d6d 100644 --- a/test/scripts/helpers/toc.js +++ b/test/scripts/helpers/toc.js @@ -3,7 +3,7 @@ const { encodeURL, escapeHTML } = require('hexo-util'); describe('toc', () => { - const toc = require('../../../lib/plugins/helper/toc'); + const toc = require('../../../dist/plugins/helper/toc'); const html = [ '

Title 1

', diff --git a/test/scripts/helpers/url_for.js b/test/scripts/helpers/url_for.js index b0b2187c7c..8f953a7d10 100644 --- a/test/scripts/helpers/url_for.js +++ b/test/scripts/helpers/url_for.js @@ -3,10 +3,10 @@ describe('url_for', () => { const ctx = { config: { url: 'https://example.com' }, - relative_url: require('../../../lib/plugins/helper/relative_url') + relative_url: require('../../../dist/plugins/helper/relative_url') }; - const urlFor = require('../../../lib/plugins/helper/url_for').bind(ctx); + const urlFor = require('../../../dist/plugins/helper/url_for').bind(ctx); it('should encode path', () => { ctx.config.root = '/'; diff --git a/test/scripts/hexo/hexo.js b/test/scripts/hexo/hexo.js index 9c0a33110d..b039ec1fb0 100644 --- a/test/scripts/hexo/hexo.js +++ b/test/scripts/hexo/hexo.js @@ -9,7 +9,7 @@ const { full_url_for } = require('hexo-util'); describe('Hexo', () => { const base_dir = join(__dirname, 'hexo_test'); - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(base_dir, { silent: true }); const coreDir = join(__dirname, '../../..'); const { version } = require('../../../package.json'); @@ -24,7 +24,7 @@ describe('Hexo', () => { } function loadAssetGenerator() { - hexo.extend.generator.register('asset', require('../../../lib/plugins/generator/asset')); + hexo.extend.generator.register('asset', require('../../../dist/plugins/generator/asset')); } before(async () => { @@ -48,7 +48,7 @@ describe('Hexo', () => { /* eslint-disable no-path-concat */ hexo.core_dir.should.eql(coreDir + sep); - hexo.lib_dir.should.eql(join(coreDir, 'lib') + sep); + hexo.lib_dir.should.eql(join(coreDir, 'dist') + sep); hexo.version.should.eql(version); hexo.base_dir.should.eql(__dirname + sep); hexo.public_dir.should.eql(join(__dirname, 'public') + sep); diff --git a/test/scripts/hexo/load_config.js b/test/scripts/hexo/load_config.js index ce9698d068..05150ff1ba 100644 --- a/test/scripts/hexo/load_config.js +++ b/test/scripts/hexo/load_config.js @@ -5,10 +5,10 @@ const { writeFile, unlink, mkdirs, rmdir } = require('hexo-fs'); const { makeRe } = require('micromatch'); describe('Load config', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'config_test'), { silent: true }); - const loadConfig = require('../../../lib/hexo/load_config'); - const defaultConfig = require('../../../lib/hexo/default_config'); + const loadConfig = require('../../../dist/hexo/load_config'); + const defaultConfig = require('../../../dist/hexo/default_config'); hexo.env.init = true; diff --git a/test/scripts/hexo/load_database.js b/test/scripts/hexo/load_database.js index 8e4de33e17..27c257e9be 100644 --- a/test/scripts/hexo/load_database.js +++ b/test/scripts/hexo/load_database.js @@ -4,9 +4,9 @@ const { join } = require('path'); const { exists, mkdirs, rmdir, unlink, writeFile } = require('hexo-fs'); describe('Load database', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'db_test'), {silent: true}); - const loadDatabase = require('../../../lib/hexo/load_database'); + const loadDatabase = require('../../../dist/hexo/load_database'); const dbPath = hexo.database.options.path; const fixture = { @@ -63,9 +63,9 @@ describe('Load database', () => { // Clean-up is not necessary (unlike the above tests), // because the db file is already removed if invalid describe('Load database - load failed', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname), {silent: true}); - const loadDatabase = require('../../../lib/hexo/load_database'); + const loadDatabase = require('../../../dist/hexo/load_database'); const dbPath = hexo.database.options.path; it('database load failed', async () => { diff --git a/test/scripts/hexo/load_plugins.js b/test/scripts/hexo/load_plugins.js index 087d7365f0..f6f7b44b17 100644 --- a/test/scripts/hexo/load_plugins.js +++ b/test/scripts/hexo/load_plugins.js @@ -5,9 +5,9 @@ const { join, dirname } = require('path'); const Promise = require('bluebird'); describe('Load plugins', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'plugin_test'), { silent: true }); - const loadPlugins = require('../../../lib/hexo/load_plugins'); + const loadPlugins = require('../../../dist/hexo/load_plugins'); const script = [ 'hexo._script_test = {', diff --git a/test/scripts/hexo/load_theme_config.js b/test/scripts/hexo/load_theme_config.js index e20e14f3ae..7dc742305b 100644 --- a/test/scripts/hexo/load_theme_config.js +++ b/test/scripts/hexo/load_theme_config.js @@ -4,9 +4,9 @@ const { join } = require('path'); const { mkdirs, unlink, writeFile, rmdir } = require('hexo-fs'); describe('Load alternate theme config', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'config_test'), {silent: true}); - const loadThemeConfig = require('../../../lib/hexo/load_theme_config'); + const loadThemeConfig = require('../../../dist/hexo/load_theme_config'); hexo.env.init = true; diff --git a/test/scripts/hexo/locals.js b/test/scripts/hexo/locals.js index 290d20f99d..9276b5ccaa 100644 --- a/test/scripts/hexo/locals.js +++ b/test/scripts/hexo/locals.js @@ -1,7 +1,7 @@ 'use strict'; describe('Locals', () => { - const Locals = require('../../../lib/hexo/locals'); + const Locals = require('../../../dist/hexo/locals'); const locals = new Locals(); it('get() - name must be a string', () => { diff --git a/test/scripts/hexo/multi_config_path.js b/test/scripts/hexo/multi_config_path.js index 37ba61f160..7cc486657d 100644 --- a/test/scripts/hexo/multi_config_path.js +++ b/test/scripts/hexo/multi_config_path.js @@ -6,10 +6,10 @@ const fs = require('hexo-fs'); const yml = require('js-yaml'); describe('config flag handling', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(pathFn.join(__dirname, 'test_dir')); - const mcp = require('../../../lib/hexo/multi_config_path')(hexo); + const mcp = require('../../../dist/hexo/multi_config_path')(hexo); const base = hexo.base_dir; function ConsoleReader() { diff --git a/test/scripts/hexo/post.js b/test/scripts/hexo/post.js index 23f39c9b1a..d2d3bbaa41 100644 --- a/test/scripts/hexo/post.js +++ b/test/scripts/hexo/post.js @@ -10,7 +10,7 @@ const fixture = require('../../fixtures/post_render'); const escapeSwigTag = str => str.replace(/{/g, '{').replace(/}/g, '}'); describe('Post', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'post_test')); require('../../../lib/plugins/highlight/')(hexo); const { post } = hexo; diff --git a/test/scripts/hexo/render.js b/test/scripts/hexo/render.js index ce82338cfb..5dc5a8c6e6 100644 --- a/test/scripts/hexo/render.js +++ b/test/scripts/hexo/render.js @@ -6,7 +6,7 @@ const yaml = require('js-yaml'); const { spy, assert: sinonAssert } = require('sinon'); describe('Render', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'render_test')); hexo.config.meta_generator = false; diff --git a/test/scripts/hexo/router.js b/test/scripts/hexo/router.js index 92c7f39ed2..5e590ee8f3 100644 --- a/test/scripts/hexo/router.js +++ b/test/scripts/hexo/router.js @@ -9,7 +9,7 @@ const { spy, assert: sinonAssert } = require('sinon'); const testUtil = require('../../util'); describe('Router', () => { - const Router = require('../../../lib/hexo/router'); + const Router = require('../../../dist/hexo/router'); const router = new Router(); function checkStream(stream, expected) { diff --git a/test/scripts/hexo/scaffold.js b/test/scripts/hexo/scaffold.js index 0a7ebbdaf4..0f432aad7f 100644 --- a/test/scripts/hexo/scaffold.js +++ b/test/scripts/hexo/scaffold.js @@ -4,7 +4,7 @@ const { join } = require('path'); const { exists, readFile, rmdir, unlink, writeFile } = require('hexo-fs'); describe('Scaffold', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); const scaffold = hexo.scaffold; const scaffoldDir = hexo.scaffold_dir; diff --git a/test/scripts/hexo/update_package.js b/test/scripts/hexo/update_package.js index 3369bc56e6..fac448627f 100644 --- a/test/scripts/hexo/update_package.js +++ b/test/scripts/hexo/update_package.js @@ -4,9 +4,9 @@ const { join } = require('path'); const { readFile, unlink, writeFile } = require('hexo-fs'); describe('Update package.json', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname, {silent: true}); - const updatePkg = require('../../../lib/hexo/update_package'); + const updatePkg = require('../../../dist/hexo/update_package'); const packagePath = join(hexo.base_dir, 'package.json'); beforeEach(() => { diff --git a/test/scripts/hexo/validate_config.js b/test/scripts/hexo/validate_config.js index 3f2b80b903..be5a9bbdb8 100644 --- a/test/scripts/hexo/validate_config.js +++ b/test/scripts/hexo/validate_config.js @@ -3,10 +3,10 @@ const { spy } = require('sinon'); describe('Validate config', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - const validateConfig = require('../../../lib/hexo/validate_config'); - const defaultConfig = require('../../../lib/hexo/default_config'); + const validateConfig = require('../../../dist/hexo/validate_config'); + const defaultConfig = require('../../../dist/hexo/default_config'); let logSpy; beforeEach(() => { diff --git a/test/scripts/models/asset.js b/test/scripts/models/asset.js index 0c3e62a107..889ba9738e 100644 --- a/test/scripts/models/asset.js +++ b/test/scripts/models/asset.js @@ -3,7 +3,7 @@ const { join } = require('path'); describe('Asset', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); const Asset = hexo.model('Asset'); diff --git a/test/scripts/models/cache.js b/test/scripts/models/cache.js index 32bc5a7efd..de8ad9d7c9 100644 --- a/test/scripts/models/cache.js +++ b/test/scripts/models/cache.js @@ -1,7 +1,7 @@ 'use strict'; describe('Cache', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); const Cache = hexo.model('Cache'); diff --git a/test/scripts/models/category.js b/test/scripts/models/category.js index 96553e68ca..d1a0da40a1 100644 --- a/test/scripts/models/category.js +++ b/test/scripts/models/category.js @@ -3,12 +3,12 @@ const { deepMerge, full_url_for } = require('hexo-util'); describe('Category', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); const Category = hexo.model('Category'); const Post = hexo.model('Post'); const PostCategory = hexo.model('PostCategory'); - const defaults = require('../../../lib/hexo/default_config'); + const defaults = require('../../../dist/hexo/default_config'); before(() => hexo.init()); diff --git a/test/scripts/models/moment.js b/test/scripts/models/moment.js index 5cc80fb0c0..e5054575b8 100644 --- a/test/scripts/models/moment.js +++ b/test/scripts/models/moment.js @@ -1,9 +1,9 @@ 'use strict'; const moment = require('moment-timezone'); +const SchemaTypeMoment = require('../../../dist/models/types/moment'); describe('SchemaTypeMoment', () => { - const SchemaTypeMoment = require('../../../lib/models/types/moment'); const type = new SchemaTypeMoment('test'); it('cast()', () => { diff --git a/test/scripts/models/page.js b/test/scripts/models/page.js index da6a520009..8a6356861e 100644 --- a/test/scripts/models/page.js +++ b/test/scripts/models/page.js @@ -4,10 +4,10 @@ const { join } = require('path'); const { deepMerge, full_url_for } = require('hexo-util'); describe('Page', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); const Page = hexo.model('Page'); - const defaults = require('../../../lib/hexo/default_config'); + const defaults = require('../../../dist/hexo/default_config'); beforeEach(() => { hexo.config = deepMerge({}, defaults); }); diff --git a/test/scripts/models/post.js b/test/scripts/models/post.js index 1c9887e9cb..e2bf189da0 100644 --- a/test/scripts/models/post.js +++ b/test/scripts/models/post.js @@ -5,7 +5,7 @@ const Promise = require('bluebird'); const { full_url_for } = require('hexo-util'); describe('Post', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); const Post = hexo.model('Post'); const Tag = hexo.model('Tag'); diff --git a/test/scripts/models/post_asset.js b/test/scripts/models/post_asset.js index 97e5ddde8f..8e6d765304 100644 --- a/test/scripts/models/post_asset.js +++ b/test/scripts/models/post_asset.js @@ -3,12 +3,12 @@ const { join } = require('path'); describe('PostAsset', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); const PostAsset = hexo.model('PostAsset'); const Post = hexo.model('Post'); let post; - const defaults = require('../../../lib/hexo/default_config'); + const defaults = require('../../../dist/hexo/default_config'); before(async () => { await hexo.init(); diff --git a/test/scripts/models/tag.js b/test/scripts/models/tag.js index 5e77692da5..7fb86124ca 100644 --- a/test/scripts/models/tag.js +++ b/test/scripts/models/tag.js @@ -3,12 +3,12 @@ const { deepMerge, full_url_for } = require('hexo-util'); describe('Tag', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); const Tag = hexo.model('Tag'); const Post = hexo.model('Post'); const PostTag = hexo.model('PostTag'); - const defaults = require('../../../lib/hexo/default_config'); + const defaults = require('../../../dist/hexo/default_config'); before(() => hexo.init()); diff --git a/test/scripts/processors/asset.js b/test/scripts/processors/asset.js index 882023898f..1b2c1a10b9 100644 --- a/test/scripts/processors/asset.js +++ b/test/scripts/processors/asset.js @@ -6,11 +6,11 @@ const { mkdirs, rmdir, stat, unlink, writeFile } = require('hexo-fs'); const dateFormat = 'YYYY-MM-DD HH:mm:ss'; describe('asset', () => { - const Hexo = require('../../../lib/hexo'); - const defaults = require('../../../lib/hexo/default_config'); + const Hexo = require('../../../dist/hexo'); + const defaults = require('../../../dist/hexo/default_config'); const baseDir = join(__dirname, 'asset_test'); const hexo = new Hexo(baseDir); - const asset = require('../../../lib/plugins/processor/asset')(hexo); + const asset = require('../../../dist/plugins/processor/asset')(hexo); const process = asset.process.bind(hexo); const { pattern } = asset; const { source } = hexo; diff --git a/test/scripts/processors/common.js b/test/scripts/processors/common.js index c0930038ca..1c4a54cd50 100644 --- a/test/scripts/processors/common.js +++ b/test/scripts/processors/common.js @@ -3,7 +3,7 @@ const moment = require('moment'); describe('common', () => { - const common = require('../../../lib/plugins/processor/common'); + const common = require('../../../dist/plugins/processor/common'); it('isTmpFile()', () => { common.isTmpFile('foo').should.be.false; diff --git a/test/scripts/processors/data.js b/test/scripts/processors/data.js index d7dab3e598..d2d1345dc1 100644 --- a/test/scripts/processors/data.js +++ b/test/scripts/processors/data.js @@ -5,10 +5,10 @@ const { mkdirs, rmdir, unlink, writeFile } = require('hexo-fs'); const { join } = require('path'); describe('data', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const baseDir = join(__dirname, 'data_test'); const hexo = new Hexo(baseDir); - const processor = require('../../../lib/plugins/processor/data')(hexo); + const processor = require('../../../dist/plugins/processor/data')(hexo); const process = Promise.method(processor.process).bind(hexo); const { source } = hexo; const { File } = source; diff --git a/test/scripts/processors/post.js b/test/scripts/processors/post.js index 5132f4670e..8d653f61ca 100644 --- a/test/scripts/processors/post.js +++ b/test/scripts/processors/post.js @@ -3,15 +3,15 @@ const { join } = require('path'); const { mkdirs, rmdir, unlink, writeFile } = require('hexo-fs'); const Promise = require('bluebird'); -const defaultConfig = require('../../../lib/hexo/default_config'); +const defaultConfig = require('../../../dist/hexo/default_config'); const dateFormat = 'YYYY-MM-DD HH:mm:ss'; describe('post', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const baseDir = join(__dirname, 'post_test'); const hexo = new Hexo(baseDir); - const post = require('../../../lib/plugins/processor/post')(hexo); + const post = require('../../../dist/plugins/processor/post')(hexo); const process = Promise.method(post.process.bind(hexo)); const { pattern } = post; const { source } = hexo; diff --git a/test/scripts/renderers/json.js b/test/scripts/renderers/json.js index aa7896229b..bdcf516a21 100644 --- a/test/scripts/renderers/json.js +++ b/test/scripts/renderers/json.js @@ -1,7 +1,7 @@ 'use strict'; describe('json', () => { - const r = require('../../../lib/plugins/renderer/json'); + const r = require('../../../dist/plugins/renderer/json'); it('normal', () => { const data = { diff --git a/test/scripts/renderers/nunjucks.js b/test/scripts/renderers/nunjucks.js index bc8717d5b3..a875211caf 100644 --- a/test/scripts/renderers/nunjucks.js +++ b/test/scripts/renderers/nunjucks.js @@ -1,7 +1,7 @@ 'use strict'; require('chai').should(); -const r = require('../../../lib/plugins/renderer/nunjucks'); +const r = require('../../../dist/plugins/renderer/nunjucks'); const { dirname, join } = require('path'); describe('nunjucks', () => { diff --git a/test/scripts/renderers/plain.js b/test/scripts/renderers/plain.js index 18d1ec0382..24982baa14 100644 --- a/test/scripts/renderers/plain.js +++ b/test/scripts/renderers/plain.js @@ -1,7 +1,7 @@ 'use strict'; describe('plain', () => { - const r = require('../../../lib/plugins/renderer/plain'); + const r = require('../../../dist/plugins/renderer/plain'); it('normal', () => { r({text: '123'}).should.eql('123'); diff --git a/test/scripts/renderers/yaml.js b/test/scripts/renderers/yaml.js index 3f734d1766..bf26b6fde0 100644 --- a/test/scripts/renderers/yaml.js +++ b/test/scripts/renderers/yaml.js @@ -1,7 +1,7 @@ 'use strict'; describe('yaml', () => { - const r = require('../../../lib/plugins/renderer/yaml'); + const r = require('../../../dist/plugins/renderer/yaml'); it('normal', () => { r({text: 'foo: 1'}).should.eql({foo: 1}); diff --git a/test/scripts/tags/asset_img.js b/test/scripts/tags/asset_img.js index d8f0709c09..3fa8817087 100644 --- a/test/scripts/tags/asset_img.js +++ b/test/scripts/tags/asset_img.js @@ -3,9 +3,9 @@ const Promise = require('bluebird'); describe('asset_img', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const assetImgTag = require('../../../lib/plugins/tag/asset_img')(hexo); + const assetImgTag = require('../../../dist/plugins/tag/asset_img')(hexo); const Post = hexo.model('Post'); const PostAsset = hexo.model('PostAsset'); let post; diff --git a/test/scripts/tags/asset_link.js b/test/scripts/tags/asset_link.js index 8a1140bc17..a75c8effba 100644 --- a/test/scripts/tags/asset_link.js +++ b/test/scripts/tags/asset_link.js @@ -3,9 +3,9 @@ const Promise = require('bluebird'); describe('asset_link', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const assetLinkTag = require('../../../lib/plugins/tag/asset_link')(hexo); + const assetLinkTag = require('../../../dist/plugins/tag/asset_link')(hexo); const Post = hexo.model('Post'); const PostAsset = hexo.model('PostAsset'); let post; diff --git a/test/scripts/tags/asset_path.js b/test/scripts/tags/asset_path.js index 20d1d4a065..281a015232 100644 --- a/test/scripts/tags/asset_path.js +++ b/test/scripts/tags/asset_path.js @@ -3,9 +3,9 @@ const Promise = require('bluebird'); describe('asset_path', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const assetPathTag = require('../../../lib/plugins/tag/asset_path')(hexo); + const assetPathTag = require('../../../dist/plugins/tag/asset_path')(hexo); const Post = hexo.model('Post'); const PostAsset = hexo.model('PostAsset'); let post; diff --git a/test/scripts/tags/blockquote.js b/test/scripts/tags/blockquote.js index 09be0d9010..d1b1661557 100644 --- a/test/scripts/tags/blockquote.js +++ b/test/scripts/tags/blockquote.js @@ -1,9 +1,9 @@ 'use strict'; describe('blockquote', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const blockquote = require('../../../lib/plugins/tag/blockquote')(hexo); + const blockquote = require('../../../dist/plugins/tag/blockquote')(hexo); before(() => hexo.init().then(() => hexo.loadPlugin(require.resolve('hexo-renderer-marked')))); diff --git a/test/scripts/tags/code.js b/test/scripts/tags/code.js index 406fe69c24..a9c2d5c966 100644 --- a/test/scripts/tags/code.js +++ b/test/scripts/tags/code.js @@ -4,10 +4,10 @@ const util = require('hexo-util'); const cheerio = require('cheerio'); describe('code', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(); - require('../../../lib/plugins/highlight/')(hexo); - const codeTag = require('../../../lib/plugins/tag/code')(hexo); + require('../../../dist/plugins/highlight/')(hexo); + const codeTag = require('../../../dist/plugins/tag/code')(hexo); const { escapeHTML } = util; const fixture = [ diff --git a/test/scripts/tags/iframe.js b/test/scripts/tags/iframe.js index b87806fc31..8f07063ccb 100644 --- a/test/scripts/tags/iframe.js +++ b/test/scripts/tags/iframe.js @@ -3,7 +3,7 @@ const cheerio = require('cheerio'); describe('iframe', () => { - const iframe = require('../../../lib/plugins/tag/iframe'); + const iframe = require('../../../dist/plugins/tag/iframe'); it('url', () => { const $ = cheerio.load(iframe(['https://zespia.tw'])); diff --git a/test/scripts/tags/img.js b/test/scripts/tags/img.js index 7030c92a41..10cd72f549 100644 --- a/test/scripts/tags/img.js +++ b/test/scripts/tags/img.js @@ -4,9 +4,9 @@ const pathFn = require('path'); const cheerio = require('cheerio'); describe('img', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(pathFn.join(__dirname, 'img_test')); - const img = require('../../../lib/plugins/tag/img')(hexo); + const img = require('../../../dist/plugins/tag/img')(hexo); before(() => hexo.init()); diff --git a/test/scripts/tags/include_code.js b/test/scripts/tags/include_code.js index ca8b4c7884..3c18068609 100644 --- a/test/scripts/tags/include_code.js +++ b/test/scripts/tags/include_code.js @@ -6,10 +6,10 @@ const { highlight, prismHighlight } = require('hexo-util'); const Promise = require('bluebird'); describe('include_code', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'include_code_test')); - require('../../../lib/plugins/highlight/')(hexo); - const includeCode = Promise.method(require('../../../lib/plugins/tag/include_code')(hexo)); + require('../../../dist/plugins/highlight/')(hexo); + const includeCode = Promise.method(require('../../../dist/plugins/tag/include_code')(hexo)); const path = join(hexo.source_dir, hexo.config.code_dir, 'test.js'); const defaultCfg = JSON.parse(JSON.stringify(hexo.config)); diff --git a/test/scripts/tags/link.js b/test/scripts/tags/link.js index 4e75d6d146..4adcdcf0cb 100644 --- a/test/scripts/tags/link.js +++ b/test/scripts/tags/link.js @@ -3,7 +3,7 @@ const cheerio = require('cheerio'); describe('link', () => { - const link = require('../../../lib/plugins/tag/link'); + const link = require('../../../dist/plugins/tag/link'); it('text + url', () => { const $ = cheerio.load(link('Click here to Google https://google.com'.split(' '))); diff --git a/test/scripts/tags/post_link.js b/test/scripts/tags/post_link.js index 22696cf553..d476933d0a 100644 --- a/test/scripts/tags/post_link.js +++ b/test/scripts/tags/post_link.js @@ -1,9 +1,9 @@ 'use strict'; describe('post_link', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const postLink = require('../../../lib/plugins/tag/post_link')(hexo); + const postLink = require('../../../dist/plugins/tag/post_link')(hexo); const Post = hexo.model('Post'); hexo.config.permalink = ':title/'; diff --git a/test/scripts/tags/post_path.js b/test/scripts/tags/post_path.js index 2b73c1edc8..5a00ecbf66 100644 --- a/test/scripts/tags/post_path.js +++ b/test/scripts/tags/post_path.js @@ -1,9 +1,9 @@ 'use strict'; describe('post_path', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const postPath = require('../../../lib/plugins/tag/post_path')(hexo); + const postPath = require('../../../dist/plugins/tag/post_path')(hexo); const Post = hexo.model('Post'); hexo.config.permalink = ':title/'; diff --git a/test/scripts/tags/pullquote.js b/test/scripts/tags/pullquote.js index acc0dc9f62..983f2a4a73 100644 --- a/test/scripts/tags/pullquote.js +++ b/test/scripts/tags/pullquote.js @@ -1,9 +1,9 @@ 'use strict'; describe('pullquote', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(__dirname); - const pullquote = require('../../../lib/plugins/tag/pullquote')(hexo); + const pullquote = require('../../../dist/plugins/tag/pullquote')(hexo); before(() => hexo.init().then(() => hexo.loadPlugin(require.resolve('hexo-renderer-marked')))); diff --git a/test/scripts/theme/theme.js b/test/scripts/theme/theme.js index 5ac61bffd1..fc3b498cf7 100644 --- a/test/scripts/theme/theme.js +++ b/test/scripts/theme/theme.js @@ -4,7 +4,7 @@ const { join } = require('path'); const { mkdirs, rmdir, writeFile } = require('hexo-fs'); describe('Theme', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'theme_test'), {silent: true}); const themeDir = join(hexo.base_dir, 'themes', 'test'); diff --git a/test/scripts/theme/view.js b/test/scripts/theme/view.js index 190e2ed98b..20d1a60aa9 100644 --- a/test/scripts/theme/view.js +++ b/test/scripts/theme/view.js @@ -6,7 +6,7 @@ const moment = require('moment'); const { fake, assert: sinonAssert } = require('sinon'); describe('View', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'theme_test')); const themeDir = join(hexo.base_dir, 'themes', 'test'); const { compile } = Object.assign({}, hexo.extend.renderer.store.njk); diff --git a/test/scripts/theme_processors/config.js b/test/scripts/theme_processors/config.js index 5363df0f84..34a61330de 100644 --- a/test/scripts/theme_processors/config.js +++ b/test/scripts/theme_processors/config.js @@ -6,10 +6,10 @@ const { mkdirs, rmdir, unlink, writeFile} = require('hexo-fs'); const Promise = require('bluebird'); describe('config', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'config_test'), {silent: true}); - const processor = require('../../../lib/theme/processors/config'); - const process = Promise.method(processor.process.bind(hexo)); + const processor = require('../../../dist/theme/processors/config'); + const process = Promise.method(processor.config.process.bind(hexo)); const themeDir = join(hexo.base_dir, 'themes', 'test'); function newFile(options) { @@ -30,7 +30,7 @@ describe('config', () => { after(() => rmdir(hexo.base_dir)); it('pattern', () => { - const pattern = processor.pattern; + const pattern = processor.config.pattern; pattern.match('_config.yml').should.be.ok; pattern.match('_config.json').should.be.ok; diff --git a/test/scripts/theme_processors/i18n.js b/test/scripts/theme_processors/i18n.js index 2e5e9e2671..84088e31af 100644 --- a/test/scripts/theme_processors/i18n.js +++ b/test/scripts/theme_processors/i18n.js @@ -5,10 +5,10 @@ const { mkdirs, rmdir, unlink, writeFile } = require('hexo-fs'); const Promise = require('bluebird'); describe('i18n', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'config_test'), {silent: true}); - const processor = require('../../../lib/theme/processors/i18n'); - const process = Promise.method(processor.process.bind(hexo)); + const processor = require('../../../dist/theme/processors/i18n'); + const process = Promise.method(processor.i18n.process.bind(hexo)); const themeDir = join(hexo.base_dir, 'themes', 'test'); function newFile(options) { @@ -33,7 +33,7 @@ describe('i18n', () => { after(() => rmdir(hexo.base_dir)); it('pattern', () => { - const pattern = processor.pattern; + const pattern = processor.i18n.pattern; pattern.match('languages/default.yml').should.be.ok; pattern.match('languages/zh-TW.yml').should.be.ok; diff --git a/test/scripts/theme_processors/source.js b/test/scripts/theme_processors/source.js index 4166abe1a1..9cf4387e45 100644 --- a/test/scripts/theme_processors/source.js +++ b/test/scripts/theme_processors/source.js @@ -5,10 +5,10 @@ const { mkdirs, rmdir, unlink, writeFile } = require('hexo-fs'); const Promise = require('bluebird'); describe('source', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'source_test'), {silent: true}); - const processor = require('../../../lib/theme/processors/source'); - const process = Promise.method(processor.process.bind(hexo)); + const processor = require('../../../dist/theme/processors/source'); + const process = Promise.method(processor.source.process.bind(hexo)); const themeDir = join(hexo.base_dir, 'themes', 'test'); const Asset = hexo.model('Asset'); @@ -33,7 +33,7 @@ describe('source', () => { after(() => rmdir(hexo.base_dir)); it('pattern', () => { - const { pattern } = processor; + const { pattern } = processor.source; pattern.match('source/foo.jpg').should.eql({path: 'foo.jpg'}); pattern.match('source/_foo.jpg').should.be.false; diff --git a/test/scripts/theme_processors/view.js b/test/scripts/theme_processors/view.js index f6171e5e33..145fc85f8e 100644 --- a/test/scripts/theme_processors/view.js +++ b/test/scripts/theme_processors/view.js @@ -5,10 +5,10 @@ const { mkdirs, rmdir, unlink, writeFile } = require('hexo-fs'); const Promise = require('bluebird'); describe('view', () => { - const Hexo = require('../../../lib/hexo'); + const Hexo = require('../../../dist/hexo'); const hexo = new Hexo(join(__dirname, 'view_test'), {silent: true}); - const processor = require('../../../lib/theme/processors/view'); - const process = Promise.method(processor.process.bind(hexo)); + const processor = require('../../../dist/theme/processors/view'); + const process = Promise.method(processor.view.process.bind(hexo)); const themeDir = join(hexo.base_dir, 'themes', 'test'); hexo.env.init = true; @@ -34,7 +34,7 @@ describe('view', () => { after(() => rmdir(hexo.base_dir)); it('pattern', () => { - const { pattern } = processor; + const { pattern } = processor.view; pattern.match('layout/index.njk').path.should.eql('index.njk'); should.not.exist(pattern.match('index.njk')); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..44cec41e42 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "sourceMap": true, + "outDir": "dist", + "declaration": true, + "esModuleInterop": true, + "types": [ + "node" + ] + }, + "include": [ + "lib/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file From 46fbdcfc98ef6d313c9a88f73b4b18079219ce7b Mon Sep 17 00:00:00 2001 From: yoshinorin Date: Sat, 18 Mar 2023 13:21:53 +0900 Subject: [PATCH 11/29] release: `v7.0.0-rc1` (#5176) * release: 7.0.0-rc1 * Update package.json --------- Co-authored-by: Mimi <1119186082@qq.com> --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f432d1f283..d7a9f7be90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hexo", - "version": "6.3.0", + "version": "7.0.0-rc1", "description": "A fast, simple & powerful blog framework, powered by Node.js.", "main": "dist/hexo", "bin": { @@ -20,6 +20,7 @@ "dist/", "bin/" ], + "types": "./dist/hexo/index.d.ts", "repository": "hexojs/hexo", "homepage": "https://hexo.io/", "funding": { From 8251df3f831d2de5fe8e5973cd194d9e1f5bf8af Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Thu, 20 Apr 2023 21:54:52 +0800 Subject: [PATCH 12/29] feat: add exclude_languages feature to prismjs (#5182) * feat: add exclude_languages feature to prismjs * feat: add exclude_languages feature to prismjs --- lib/hexo/default_config.ts | 3 ++- lib/plugins/highlight/prism.ts | 4 ++++ test/scripts/filters/backtick_code_block.js | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/hexo/default_config.ts b/lib/hexo/default_config.ts index 379f80737e..5e01f5781d 100644 --- a/lib/hexo/default_config.ts +++ b/lib/hexo/default_config.ts @@ -51,7 +51,8 @@ export = { prismjs: { preprocess: true, line_number: true, - tab_replace: '' + tab_replace: '', + exclude_languages: [] }, // Category & Tag default_category: 'uncategorized', diff --git a/lib/plugins/highlight/prism.ts b/lib/plugins/highlight/prism.ts index 1e37674fd0..33304068d4 100644 --- a/lib/plugins/highlight/prism.ts +++ b/lib/plugins/highlight/prism.ts @@ -20,5 +20,9 @@ module.exports = function(code, options) { if (!prismHighlight) prismHighlight = require('hexo-util').prismHighlight; + if (Array.isArray(prismjsCfg.exclude_languages) && prismjsCfg.exclude_languages.includes(prismjsOptions.lang)) { + // Only wrap with
+ return `
${require('hexo-util').escapeHTML(code)}
`; + } return prismHighlight(code, prismjsOptions); }; diff --git a/test/scripts/filters/backtick_code_block.js b/test/scripts/filters/backtick_code_block.js index 4b7c932f52..5c75bbccdb 100644 --- a/test/scripts/filters/backtick_code_block.js +++ b/test/scripts/filters/backtick_code_block.js @@ -635,5 +635,20 @@ describe('Backtick code block', () => { codeBlock(data); data.content.should.eql('' + expected + ''); }); + + it('prism only wrap with pre and code', () => { + hexo.config.prismjs.exclude_languages = ['js']; + const data = { + content: [ + '``` js', + code, + '```' + ].join('\n') + }; + const escapeSwigTag = str => str.replace(/{/g, '{').replace(/}/g, '}'); + const expected = `
${escapeSwigTag(util.escapeHTML(code))}
`; + codeBlock(data); + data.content.should.eql('' + expected + ''); + }); }); }); From 725422ae052591b20c71bc8288ab29849c74dc4c Mon Sep 17 00:00:00 2001 From: Pcrab Date: Thu, 20 Apr 2023 21:56:05 +0800 Subject: [PATCH 13/29] Refactor types (#5178) * refactor: add types for some explicit any fields * refactor: add better extend types * refactor: add type Hexo for ctx * reafactor: better function type * style: use import type for type only imports * fix: wrong type for args and options --- lib/box/index.ts | 2 +- lib/extend/console.ts | 59 +++++++++++++++++++++--------- lib/extend/deployer.ts | 14 ++++++-- lib/extend/filter.ts | 15 ++++---- lib/extend/generator.ts | 34 +++++++++++++++--- lib/extend/helper.ts | 23 ++++++++---- lib/extend/injector.ts | 18 +++++++--- lib/extend/migrator.ts | 11 ++++-- lib/extend/processor.ts | 19 ++++++++-- lib/extend/renderer.ts | 65 +++++++++++++++++++++++++++------ lib/extend/syntax_highlight.ts | 32 +++++++++++++---- lib/extend/tag.ts | 36 +++++++++++++------ lib/hexo/index.ts | 66 +++++++++++++++++++++------------- lib/plugins/console/index.ts | 4 ++- lib/plugins/filter/index.ts | 4 ++- lib/plugins/generator/asset.ts | 2 +- lib/plugins/generator/index.ts | 4 ++- lib/plugins/helper/index.ts | 4 ++- lib/plugins/highlight/index.ts | 4 ++- lib/plugins/injector/index.ts | 4 ++- lib/plugins/processor/index.ts | 6 ++-- lib/plugins/renderer/index.ts | 4 ++- lib/plugins/tag/index.ts | 3 +- package.json | 3 +- 24 files changed, 327 insertions(+), 109 deletions(-) diff --git a/lib/box/index.ts b/lib/box/index.ts index 5dceb37784..5f8978d6fc 100644 --- a/lib/box/index.ts +++ b/lib/box/index.ts @@ -182,7 +182,7 @@ class Box extends EventEmitter { }).thenReturn(path); } - watch(callback) { + watch(callback?) { if (this.isWatching()) { return BlueBirdPromise.reject(new Error('Watcher has already started.')).asCallback(callback); } diff --git a/lib/extend/console.ts b/lib/extend/console.ts index 6a977a25a8..c4af6322d7 100644 --- a/lib/extend/console.ts +++ b/lib/extend/console.ts @@ -1,17 +1,40 @@ import Promise from 'bluebird'; import abbrev from 'abbrev'; -/** - * Console plugin option - * @typedef {Object} Option - * @property {String} usage - The usage of a console command - * @property {{name: String, desc: String}[]} arguments - The description of each argument of a console command - * @property {{name: String, desc: String}[]} options - The description of each option of a console command - */ +type Option = Partial<{ + usage: string; + desc: string; + init: boolean; + arguments: { + name: string; + desc: string; + }[]; + options: { + name: string; + desc: string; + }[]; +}> + +interface Args { + _: string[]; + [key: string]: string | boolean | string[]; +} +type AnyFn = (args: Args) => any; +interface StoreFunction extends AnyFn { + desc?: string; + options?: Option; +} + +interface Store { + [key: string]: StoreFunction +} +interface Alias { + [key: string]: string +} class Console { - public store: any; - public alias: any; + public store: Store; + public alias: Alias; constructor() { this.store = {}; @@ -21,9 +44,9 @@ class Console { /** * Get a console plugin function by name * @param {String} name - The name of the console plugin - * @returns {Function} - The console plugin function + * @returns {StoreFunction} - The console plugin function */ - get(name) { + get(name: string): StoreFunction { name = name.toLowerCase(); return this.store[this.alias[name]]; } @@ -37,9 +60,13 @@ class Console { * @param {String} name - The name of console plugin to be registered * @param {String} desc - More detailed information about a console command * @param {Option} options - The description of each option of a console command - * @param {Function} fn - The console plugin to be registered + * @param {AnyFn} fn - The console plugin to be registered */ - register(name, desc, options, fn) { + register(name: string, fn: AnyFn): void + register(name: string, desc: string, fn: AnyFn): void + register(name: string, options: Option, fn: AnyFn): void + register(name: string, desc: string, options: Option, fn: AnyFn): void + register(name: string, desc: string | Option | AnyFn, options?: Option | AnyFn, fn?: AnyFn) { if (!name) throw new TypeError('name is required'); if (!fn) { @@ -74,10 +101,10 @@ class Console { fn = Promise.method(fn); } - const c = fn; + const c = fn as StoreFunction; this.store[name.toLowerCase()] = c; - c.options = options; - c.desc = desc; + c.options = options as Option; + c.desc = desc as string; this.alias = abbrev(Object.keys(this.store)); } diff --git a/lib/extend/deployer.ts b/lib/extend/deployer.ts index b743071fdb..d42d3d854c 100644 --- a/lib/extend/deployer.ts +++ b/lib/extend/deployer.ts @@ -1,7 +1,17 @@ import Promise from 'bluebird'; +interface StoreFunction { + (deployArg: { + type: string; + [key: string]: any + }) : any; +} +interface Store { + [key: string]: StoreFunction +} + class Deployer { - public store: any; + public store: Store; constructor() { this.store = {}; @@ -15,7 +25,7 @@ class Deployer { return this.store[name]; } - register(name: string, fn) { + register(name: string, fn: StoreFunction) { if (!name) throw new TypeError('name is required'); if (typeof fn !== 'function') throw new TypeError('fn must be a function'); diff --git a/lib/extend/filter.ts b/lib/extend/filter.ts index eba129cc1b..78113d01c2 100644 --- a/lib/extend/filter.ts +++ b/lib/extend/filter.ts @@ -8,11 +8,11 @@ const typeAlias = { interface FilterOptions { context?: any; - args?: any; + args?: any[]; } interface StoreFunction { - (...args: any[]): any; + (data?: any, ...args: any[]): any; priority?: number; } @@ -34,8 +34,11 @@ class Filter { return this.store[type] || []; } - register(fn: StoreFunction, priority: number); - register(type?: string | StoreFunction, fn?: StoreFunction | number, priority?: number) { + register(fn: StoreFunction): void + register(fn: StoreFunction, priority: number): void + register(type: string, fn: StoreFunction): void + register(type: string, fn: StoreFunction, priority: number): void + register(type: string | StoreFunction, fn?: StoreFunction | number, priority?: number) { if (!priority) { if (typeof type === 'function') { priority = fn as number; @@ -72,7 +75,7 @@ class Filter { if (index !== -1) list.splice(index, 1); } - exec(type: string, data, options: FilterOptions = {}) { + exec(type: string, data: any[], options: FilterOptions = {}) { const filters = this.list(type); if (filters.length === 0) return Promise.resolve(data); @@ -87,7 +90,7 @@ class Filter { })).then(() => args[0]); } - execSync(type: string, data, options: FilterOptions = {}) { + execSync(type: string, data: any[], options: FilterOptions = {}) { const filters = this.list(type); const filtersLen = filters.length; if (filtersLen === 0) return data; diff --git a/lib/extend/generator.ts b/lib/extend/generator.ts index 41a4a07b12..6360d1eb2c 100644 --- a/lib/extend/generator.ts +++ b/lib/extend/generator.ts @@ -1,8 +1,30 @@ import Promise from 'bluebird'; +interface BaseObj { + path: string; + data: any; + layout?: string; +} +type ReturnType = BaseObj | BaseObj[]; +type GeneratorReturnType = ReturnType | Promise; + +interface GeneratorFunction { + (locals: object): GeneratorReturnType; +} + +type StoreFunctionReturn = Promise; + +interface StoreFunction { + (locals: object): StoreFunctionReturn; +} + +interface Store { + [key: string]: StoreFunction +} + class Generator { - public id: any; - public store: any; + public id: number; + public store: Store; constructor() { this.id = 0; @@ -17,9 +39,11 @@ class Generator { return this.store[name]; } - register(name, fn) { + register(fn: GeneratorFunction): void + register(name: string, fn: GeneratorFunction): void + register(name: string | GeneratorFunction, fn?: GeneratorFunction) { if (!fn) { - if (typeof name === 'function') { + if (typeof name === 'function') { // fn fn = name; name = `generator-${this.id++}`; } else { @@ -28,7 +52,7 @@ class Generator { } if (fn.length > 1) fn = Promise.promisify(fn); - this.store[name] = Promise.method(fn); + this.store[name as string] = Promise.method(fn); } } diff --git a/lib/extend/helper.ts b/lib/extend/helper.ts index fe0500fdd1..7903557c97 100644 --- a/lib/extend/helper.ts +++ b/lib/extend/helper.ts @@ -1,32 +1,41 @@ +interface StoreFunction { + (...args: any[]): string; +} + +interface Store { + [key: string]: StoreFunction +} + + class Helper { - public store: any; + public store: Store; constructor() { this.store = {}; } /** - * @returns {Object} - The plugin store + * @returns {Store} - The plugin store */ - list() { + list(): Store { return this.store; } /** * Get helper plugin function by name * @param {String} name - The name of the helper plugin - * @returns {Function} + * @returns {StoreFunction} */ - get(name: string) { + get(name: string): StoreFunction { return this.store[name]; } /** * Register a helper plugin * @param {String} name - The name of the helper plugin - * @param {Function} fn - The helper plugin function + * @param {StoreFunction} fn - The helper plugin function */ - register(name: string, fn) { + register(name: string, fn: StoreFunction) { if (!name) throw new TypeError('name is required'); if (typeof fn !== 'function') throw new TypeError('fn must be a function'); diff --git a/lib/extend/injector.ts b/lib/extend/injector.ts index 7802152efd..fd1d09acdd 100644 --- a/lib/extend/injector.ts +++ b/lib/extend/injector.ts @@ -1,7 +1,15 @@ import { Cache } from 'hexo-util'; +type Entry = 'head_begin' | 'head_end' | 'body_begin' | 'body_end'; + +type Store = { + [key in Entry]: { + [key: string]: Set; + }; +}; + class Injector { - public store: any; + public store: Store; public cache: any; public page: any; @@ -20,21 +28,21 @@ class Injector { return this.store; } - get(entry, to = 'default') { + get(entry: Entry, to = 'default') { return Array.from(this.store[entry][to] || []); } - getText(entry, to = 'default') { + getText(entry: Entry, to = 'default') { const arr = this.get(entry, to); if (!arr || !arr.length) return ''; return arr.join(''); } - getSize(entry) { + getSize(entry: Entry) { return this.cache.apply(`${entry}-size`, Object.keys(this.store[entry]).length); } - register(entry, value, to = 'default') { + register(entry: Entry, value: string | (() => string), to = 'default') { if (!entry) throw new TypeError('entry is required'); if (typeof value === 'function') value = value(); diff --git a/lib/extend/migrator.ts b/lib/extend/migrator.ts index 94e725dc0c..2a149f191a 100644 --- a/lib/extend/migrator.ts +++ b/lib/extend/migrator.ts @@ -1,7 +1,14 @@ import Promise from 'bluebird'; +interface StoreFunction { + (args: any): any +} + +interface Store { + [key: string]: StoreFunction +} class Migrator { - public store: any; + public store: Store; constructor() { this.store = {}; @@ -15,7 +22,7 @@ class Migrator { return this.store[name]; } - register(name: string, fn) { + register(name: string, fn: StoreFunction) { if (!name) throw new TypeError('name is required'); if (typeof fn !== 'function') throw new TypeError('fn must be a function'); diff --git a/lib/extend/processor.ts b/lib/extend/processor.ts index b3bcb8e544..0af6998494 100644 --- a/lib/extend/processor.ts +++ b/lib/extend/processor.ts @@ -1,8 +1,19 @@ import Promise from 'bluebird'; import { Pattern } from 'hexo-util'; +import type File from '../box/file'; +interface StoreFunction { + (file: File): any +} + +type Store = { + pattern: Pattern; + process: StoreFunction + }[]; + +type patternType = Exclude[0], ((str: string) => string)>; class Processor { - public store: any; + public store: Store; constructor() { this.store = []; @@ -12,7 +23,9 @@ class Processor { return this.store; } - register(pattern, fn) { + register(fn: StoreFunction): void; + register(pattern: patternType, fn: StoreFunction): void; + register(pattern: patternType | StoreFunction, fn?: StoreFunction) { if (!fn) { if (typeof pattern === 'function') { fn = pattern; @@ -29,7 +42,7 @@ class Processor { } this.store.push({ - pattern: new Pattern(pattern), + pattern: new Pattern(pattern as patternType), process: fn }); } diff --git a/lib/extend/renderer.ts b/lib/extend/renderer.ts index e2782dfdba..c70e054f18 100644 --- a/lib/extend/renderer.ts +++ b/lib/extend/renderer.ts @@ -1,46 +1,90 @@ import { extname } from 'path'; import Promise from 'bluebird'; -const getExtname = str => { +const getExtname = (str: string) => { if (typeof str !== 'string') return ''; const ext = extname(str) || str; return ext.startsWith('.') ? ext.slice(1) : ext; }; +interface StoreSyncFunction { + ( + data: { + path?: string; + text: string; + }, + options: object, + // callback: (err: Error, value: string) => any + ): any; + output?: string; + compile?: (local: object) => string; +} +interface StoreFunction { + ( + data: { + path?: string; + text: string; + }, + options: object, + ): Promise; + ( + data: { + path?: string; + text: string; + }, + options: object, + callback: (err: Error, value: string) => any + ): void; + output?: string; + compile?: (local: object) => string; + disableNunjucks?: boolean; +} + +interface SyncStore { + [key: string]: StoreSyncFunction; +} +interface Store { + [key: string]: StoreFunction; +} + class Renderer { - public store: any; - public storeSync: any; + public store: Store; + public storeSync: SyncStore; constructor() { this.store = {}; this.storeSync = {}; } - list(sync) { + list(sync: boolean) { return sync ? this.storeSync : this.store; } - get(name, sync?) { + get(name: string, sync?: boolean) { const store = this[sync ? 'storeSync' : 'store']; return store[getExtname(name)] || store[name]; } - isRenderable(path) { + isRenderable(path: string) { return Boolean(this.get(path)); } - isRenderableSync(path) { + isRenderableSync(path: string) { return Boolean(this.get(path, true)); } - getOutput(path) { + getOutput(path: string) { const renderer = this.get(path); return renderer ? renderer.output : ''; } - register(name, output, fn, sync) { + register(name: string, output: string, fn: StoreFunction): void; + register(name: string, output: string, fn: StoreFunction, sync: false): void; + register(name: string, output: string, fn: StoreSyncFunction, sync: true): void; + register(name: string, output: string, fn: StoreFunction | StoreSyncFunction, sync: boolean): void; + register(name: string, output: string, fn: StoreFunction | StoreSyncFunction, sync?: boolean) { if (!name) throw new TypeError('name is required'); if (!output) throw new TypeError('output is required'); if (typeof fn !== 'function') throw new TypeError('fn must be a function'); @@ -53,7 +97,8 @@ class Renderer { this.storeSync[name].output = output; this.store[name] = Promise.method(fn); - this.store[name].disableNunjucks = fn.disableNunjucks; + // eslint-disable-next-line no-extra-parens + this.store[name].disableNunjucks = (fn as StoreFunction).disableNunjucks; } else { if (fn.length > 2) fn = Promise.promisify(fn); this.store[name] = fn; diff --git a/lib/extend/syntax_highlight.ts b/lib/extend/syntax_highlight.ts index 22d9371a5e..1ece414224 100644 --- a/lib/extend/syntax_highlight.ts +++ b/lib/extend/syntax_highlight.ts @@ -1,10 +1,30 @@ -interface Options { - context?: any; - args?: any; +import type Hexo from '../hexo'; + +export interface HighlightOptions { + lang: string | undefined, + caption: string | undefined, + lines_length: number, + + // plulgins/filter/before_post_render/backtick_code_block + firstLineNumber?: string | number + + // plugins/tag/code.ts + language_attr?: boolean | undefined; + firstLine?: number; + line_number?: boolean | undefined; + line_threshold?: number | undefined; + mark?: number[]; + wrap?: boolean | undefined; + +} + +interface HighlightExecArgs { + context?: Hexo; + args?: [string, HighlightOptions]; } interface StoreFunction { - (...args: any[]): any; + (content: string, options: HighlightOptions): string; priority?: number; } @@ -29,7 +49,7 @@ class SyntaxHighlight { return name && this.store[name]; } - exec(name: string, options: Options) { + exec(name: string, options: HighlightExecArgs): string { const fn = this.store[name]; if (!fn) throw new TypeError(`syntax highlighter ${name} is not registered`); @@ -40,4 +60,4 @@ class SyntaxHighlight { } } -export = SyntaxHighlight; +export default SyntaxHighlight; diff --git a/lib/extend/tag.ts b/lib/extend/tag.ts index b2bcd2fcfd..dbebd5bfac 100644 --- a/lib/extend/tag.ts +++ b/lib/extend/tag.ts @@ -6,11 +6,18 @@ const rSwigRawFullBlock = /{% *raw *%}/; const rCodeTag = /]*>[\s\S]+?<\/code>/g; const escapeSwigTag = str => str.replace(/{/g, '{').replace(/}/g, '}'); +interface TagFunction { + (args: any[], content: string): string; +} +interface AsyncTagFunction { + (args: any[], content: string): Promise; +} + class NunjucksTag { - public tags: any; - public fn: any; + public tags: string[]; + public fn: TagFunction | AsyncTagFunction; - constructor(name, fn) { + constructor(name: string, fn: TagFunction | AsyncTagFunction) { this.tags = [name]; this.fn = fn; } @@ -186,6 +193,11 @@ const formatNunjucksError = (err, input, source = '') => { return e; }; +type RegisterOptions = { + async?: boolean; + ends?: boolean; +} + class Tag { public env: any; public source: any; @@ -196,27 +208,31 @@ class Tag { }); } - register(name, fn, options) { + register(name: string, fn: TagFunction): void + register(name: string, fn: TagFunction, ends: boolean): void + register(name: string, fn: TagFunction, options: RegisterOptions): void + register(name: string, fn: TagFunction, options?: RegisterOptions | boolean) { if (!name) throw new TypeError('name is required'); if (typeof fn !== 'function') throw new TypeError('fn must be a function'); if (options == null || typeof options === 'boolean') { - options = { ends: options }; + options = { ends: options as boolean }; } - let tag; + let tag: NunjucksTag; if (options.async) { + let asyncFn: AsyncTagFunction; if (fn.length > 2) { - fn = Promise.promisify(fn); + asyncFn = Promise.promisify(fn); } else { - fn = Promise.method(fn); + asyncFn = Promise.method(fn); } if (options.ends) { - tag = new NunjucksAsyncBlock(name, fn); + tag = new NunjucksAsyncBlock(name, asyncFn); } else { - tag = new NunjucksAsyncTag(name, fn); + tag = new NunjucksAsyncTag(name, asyncFn); } } else if (options.ends) { tag = new NunjucksBlock(name, fn); diff --git a/lib/hexo/index.ts b/lib/hexo/index.ts index 023f78f81d..15a0d6403e 100644 --- a/lib/hexo/index.ts +++ b/lib/hexo/index.ts @@ -117,6 +117,25 @@ interface Query { published?: boolean; } +interface Extend { + console: Console, + deployer: Deployer, + filter: Filter, + generator: Generator, + helper: Helper, + highlight: Highlight, + injector: Injector, + migrator: Migrator, + processor: Processor, + renderer: Renderer, + tag: Tag +} + +type DefaultConfigType = typeof defaultConfig; +interface Config extends DefaultConfigType { + [key: string]: any; +} + // Node.js internal APIs declare module 'module' { function _nodeModulePaths(path: string): string[]; @@ -126,32 +145,31 @@ declare module 'module' { } class Hexo extends EventEmitter { - public base_dir: any; - public public_dir: any; - public source_dir: any; - public plugin_dir: any; - public script_dir: any; - public scaffold_dir: any; - public theme_dir: any; - public theme_script_dir: any; + public base_dir: string; + public public_dir: string; + public source_dir: string; + public plugin_dir: string; + public script_dir: string; + public scaffold_dir: string; + public theme_dir: string; + public theme_script_dir: string; public env: any; - public extend: any; - public config: any; - public log: any; - public render: any; - public route: any; - public post: any; - public scaffold: any; - public _dbLoaded: any; - public _isGenerating: any; + public extend: Extend; + public config: Config; + public log: ReturnType; + public render: Render; + public route: Router; + public post: Post; + public scaffold: Scaffold; + public _dbLoaded: boolean; + public _isGenerating: boolean; public database: Database; - public config_path: any; - public source: any; - public theme: any; - public locals: any; - public version: any; - public emit: any; - public _watchBox: any; + public config_path: string; + public source: Source; + public theme: Theme; + public locals: Locals; + public version: string; + public _watchBox: () => void; public page: any; public path: any; public url: any; diff --git a/lib/plugins/console/index.ts b/lib/plugins/console/index.ts index 829f8f0baf..dc4b6e5f40 100644 --- a/lib/plugins/console/index.ts +++ b/lib/plugins/console/index.ts @@ -1,4 +1,6 @@ -export = function(ctx) { +import type Hexo from '../../hexo'; + +export = function(ctx: Hexo) { const { console } = ctx.extend; console.register('clean', 'Remove generated files and cache.', require('./clean')); diff --git a/lib/plugins/filter/index.ts b/lib/plugins/filter/index.ts index 612e116ece..26aed0bf0d 100644 --- a/lib/plugins/filter/index.ts +++ b/lib/plugins/filter/index.ts @@ -1,4 +1,6 @@ -export = ctx => { +import type Hexo from '../../hexo'; + +export = (ctx: Hexo) => { const { filter } = ctx.extend; require('./after_render')(ctx); diff --git a/lib/plugins/generator/asset.ts b/lib/plugins/generator/asset.ts index b7dcb47a83..722807c52e 100644 --- a/lib/plugins/generator/asset.ts +++ b/lib/plugins/generator/asset.ts @@ -3,7 +3,7 @@ import { exists, createReadStream } from 'hexo-fs'; import Promise from 'bluebird'; import { extname } from 'path'; import { magenta } from 'picocolors'; -import warehouse from 'warehouse'; +import type warehouse from 'warehouse'; interface Data { modified: boolean; diff --git a/lib/plugins/generator/index.ts b/lib/plugins/generator/index.ts index a07031c380..9c65363065 100644 --- a/lib/plugins/generator/index.ts +++ b/lib/plugins/generator/index.ts @@ -1,4 +1,6 @@ -export = ctx => { +import type Hexo from '../../hexo'; + +export = (ctx: Hexo) => { const { generator } = ctx.extend; generator.register('asset', require('./asset')); diff --git a/lib/plugins/helper/index.ts b/lib/plugins/helper/index.ts index 79adc27b7d..8a90bc1132 100644 --- a/lib/plugins/helper/index.ts +++ b/lib/plugins/helper/index.ts @@ -1,4 +1,6 @@ -export = ctx => { +import type Hexo from '../../hexo'; + +export = (ctx: Hexo) => { const { helper } = ctx.extend; const date = require('./date'); diff --git a/lib/plugins/highlight/index.ts b/lib/plugins/highlight/index.ts index 2efad0cbf6..14da505e7f 100644 --- a/lib/plugins/highlight/index.ts +++ b/lib/plugins/highlight/index.ts @@ -1,4 +1,6 @@ -module.exports = ctx => { +import type Hexo from '../../hexo'; + +module.exports = (ctx: Hexo) => { const { highlight } = ctx.extend; highlight.register('highlight.js', require('./highlight')); diff --git a/lib/plugins/injector/index.ts b/lib/plugins/injector/index.ts index 5c7d54f6ac..6736417bc8 100644 --- a/lib/plugins/injector/index.ts +++ b/lib/plugins/injector/index.ts @@ -1,4 +1,6 @@ -export = ctx => { +import type Hexo from '../../hexo'; + +export = (ctx: Hexo) => { // eslint-disable-next-line no-unused-vars const { injector } = ctx.extend; }; diff --git a/lib/plugins/processor/index.ts b/lib/plugins/processor/index.ts index 1161ff7730..e7ae2c580c 100644 --- a/lib/plugins/processor/index.ts +++ b/lib/plugins/processor/index.ts @@ -1,7 +1,9 @@ -export = ctx => { +import type Hexo from '../../hexo'; + +export = (ctx: Hexo) => { const { processor } = ctx.extend; - function register(name) { + function register(name: string) { const obj = require(`./${name}`)(ctx); processor.register(obj.pattern, obj.process); } diff --git a/lib/plugins/renderer/index.ts b/lib/plugins/renderer/index.ts index c5e6969601..c8529c5a57 100644 --- a/lib/plugins/renderer/index.ts +++ b/lib/plugins/renderer/index.ts @@ -1,4 +1,6 @@ -export = ctx => { +import type Hexo from '../../hexo'; + +export = (ctx: Hexo) => { const { renderer } = ctx.extend; const plain = require('./plain'); diff --git a/lib/plugins/tag/index.ts b/lib/plugins/tag/index.ts index a136ead63f..af7b513211 100644 --- a/lib/plugins/tag/index.ts +++ b/lib/plugins/tag/index.ts @@ -1,6 +1,7 @@ import moize from 'moize'; +import type Hexo from '../../hexo'; -export default ctx => { +export default (ctx: Hexo) => { const { tag } = ctx.extend; const blockquote = require('./blockquote')(ctx); diff --git a/package.json b/package.json index d7a9f7be90..e6593d3392 100644 --- a/package.json +++ b/package.json @@ -66,12 +66,13 @@ "warehouse": "^5.0.0" }, "devDependencies": { + "0x": "^5.1.2", "@easyops/git-exec-and-restage": "^1.0.4", "@types/bluebird": "^3.5.37", "@types/node": "^18.11.8", + "@types/nunjucks": "^3.2.2", "@typescript-eslint/eslint-plugin": "^5.41.0", "@typescript-eslint/parser": "^5.41.0", - "0x": "^5.1.2", "c8": "^7.12.0", "chai": "^4.3.6", "cheerio": "0.22.0", From c62909deb607ea104a74c84e83846ca0b0758221 Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Sun, 21 May 2023 00:45:49 +0800 Subject: [PATCH 14/29] fix(backtick_code): handle empty code blocks (#5206) --- .../before_post_render/backtick_code_block.ts | 2 +- test/scripts/filters/backtick_code_block.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/plugins/filter/before_post_render/backtick_code_block.ts b/lib/plugins/filter/before_post_render/backtick_code_block.ts index b9df3e60f2..802ed7edd3 100644 --- a/lib/plugins/filter/before_post_render/backtick_code_block.ts +++ b/lib/plugins/filter/before_post_render/backtick_code_block.ts @@ -1,4 +1,4 @@ -const rBacktick = /^((?:[^\S\r\n]*>){0,3}[^\S\r\n]*)(`{3,}|~{3,})[^\S\r\n]*((?:.*?[^`\s])?)[^\S\r\n]*\n((?:[\s\S]*?\n)?)(?:(?:[^\S\r\n]*>){0,3}[^\S\r\n]*)\2[^\S\r\n]?(\n+|$)/gm; +const rBacktick = /^((?:[^\S\r\n]*>){0,3}[^\S\r\n]*)(`{3,}|~{3,})[^\S\r\n]*((?:.*?[^`\s])?)[^\S\r\n]*\n((?:[\s\S]*?\n)*?)(?:(?:[^\S\r\n]*>){0,3}[^\S\r\n]*)\2[^\S\r\n]?(\n+|$)/gm; const rAllOptions = /([^\s]+)\s+(.+?)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/; const rLangCaption = /([^\s]+)\s*(.+)?/; diff --git a/test/scripts/filters/backtick_code_block.js b/test/scripts/filters/backtick_code_block.js index 5c75bbccdb..b195d76a8e 100644 --- a/test/scripts/filters/backtick_code_block.js +++ b/test/scripts/filters/backtick_code_block.js @@ -650,5 +650,19 @@ describe('Backtick code block', () => { codeBlock(data); data.content.should.eql('' + expected + ''); }); + + it('handle empty code block', () => { + const data = { + content: [ + '``` js', + '```', + '# New line', + '``` js', + '```' + ].join('\n') + }; + codeBlock(data); + data.content.match(//g).length.should.eql(2); + }); }); }); From f79136203ba6d2a3c2b35afe4bf05e6774e83abb Mon Sep 17 00:00:00 2001 From: Xianwei Pang Date: Thu, 1 Jun 2023 07:40:25 +0800 Subject: [PATCH 15/29] chore: change dependencies version (#5202) * chore: change dependencies version * chore: ignore pnpm lock file --- .gitignore | 1 + package.json | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 67d6810998..24b48ae15f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ tmp/ .idea/ yarn.lock package-lock.json +pnpm-lock.yaml .nyc_output/ coverage/ .tmp* diff --git a/package.json b/package.json index e6593d3392..486140b30a 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "archy": "^1.0.0", "bluebird": "^3.7.2", "hexo-cli": "^4.3.0", - "hexo-front-matter": "^4.0.0", + "hexo-front-matter": "4.0.0", "hexo-fs": "^4.1.1", "hexo-i18n": "^2.0.0", "hexo-log": "^4.0.1", @@ -52,7 +52,7 @@ "js-yaml": "^4.1.0", "js-yaml-js-types": "^1.0.0", "micromatch": "^4.0.4", - "moize": "^6.1.0", + "moize": "^6.1.6", "moment": "^2.29.1", "moment-timezone": "^0.5.34", "nunjucks": "^3.2.3", From 5837bb80ff432d932984b4cc7a394a3cb2d88310 Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Sat, 3 Jun 2023 01:32:28 +0800 Subject: [PATCH 16/29] feat(tags/post_link): use slug when title is empty (#5220) --- lib/plugins/tag/post_link.ts | 4 ++-- test/scripts/tags/post_link.js | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/plugins/tag/post_link.ts b/lib/plugins/tag/post_link.ts index 4460cef8fe..782714a1d2 100644 --- a/lib/plugins/tag/post_link.ts +++ b/lib/plugins/tag/post_link.ts @@ -27,9 +27,9 @@ export = ctx => { throw new Error(`Post not found: post_link ${slug}.`); } - let title = args.length ? args.join(' ') : post.title; + let title = args.length ? args.join(' ') : post.title || post.slug; // Let attribute be the true post title so it appears in tooltip. - const attrTitle = escapeHTML(post.title); + const attrTitle = escapeHTML(post.title || post.slug); if (escape === 'true') title = escapeHTML(title); const link = encodeURL(new URL(post.path, ctx.config.url).pathname); diff --git a/test/scripts/tags/post_link.js b/test/scripts/tags/post_link.js index d476933d0a..999f2cad48 100644 --- a/test/scripts/tags/post_link.js +++ b/test/scripts/tags/post_link.js @@ -22,6 +22,11 @@ describe('post_link', () => { source: 'fôo', slug: 'fôo', title: 'Hello world' + }, + { + source: 'no-title', + slug: 'no-title', + title: '' }]))); it('default', () => { @@ -36,6 +41,10 @@ describe('post_link', () => { postLink(['foo', 'test']).should.eql('test'); }); + it('no title', () => { + postLink(['no-title']).should.eql('no-title'); + }); + it('should escape tag in title by default', () => { postLink(['title-with-tag']).should.eql('"Hello" <new world>!'); }); From 5ee3e6d0c51d95c5cd5515cc514b0ce886c4cb7f Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Sat, 3 Jun 2023 01:32:53 +0800 Subject: [PATCH 17/29] test: improve coverage (#5221) * test: improve coverage * test(processors): improve coverage * test(processors): improve coverage * test(helpers): improve coverage * test(console): improve coverage --- test/scripts/console/list_page.js | 14 +++++++ test/scripts/console/list_post.js | 11 ++++- test/scripts/console/list_route.js | 10 +++++ test/scripts/console/new.js | 31 ++++++++++++++ test/scripts/helpers/paginator.js | 18 ++++++++ test/scripts/processors/asset.js | 43 +++++++++++++++++++ test/scripts/processors/data.js | 27 ++++++++++++ test/scripts/processors/post.js | 67 ++++++++++++++++++++++++++++++ test/scripts/renderers/nunjucks.js | 8 ++++ 9 files changed, 228 insertions(+), 1 deletion(-) diff --git a/test/scripts/console/list_page.js b/test/scripts/console/list_page.js index 080a6993b6..dc8fd444ba 100644 --- a/test/scripts/console/list_page.js +++ b/test/scripts/console/list_page.js @@ -39,4 +39,18 @@ describe('Console list', () => { sinonAssert.calledWithMatch(logStub, 'Hello World'); sinonAssert.calledWithMatch(logStub, 'foo'); }); + + it('page with unicode', async () => { + await Page.insert({ + source: 'foo', + title: '\u0100', + path: 'bar' + }); + listPages(); + sinonAssert.calledWithMatch(logStub, 'Date'); + sinonAssert.calledWithMatch(logStub, 'Title'); + sinonAssert.calledWithMatch(logStub, 'Path'); + sinonAssert.calledWithMatch(logStub, '\u0100'); + sinonAssert.calledWithMatch(logStub, 'foo'); + }); }); diff --git a/test/scripts/console/list_post.js b/test/scripts/console/list_post.js index 23376a2bcc..64ab652d3b 100644 --- a/test/scripts/console/list_post.js +++ b/test/scripts/console/list_post.js @@ -1,5 +1,6 @@ 'use strict'; +const Promise = require('bluebird'); const { stub, assert: sinonAssert } = require('sinon'); describe('Console list', () => { @@ -34,8 +35,15 @@ describe('Console list', () => { {source: 'baz', slug: 'baz', title: 'Dude', date: 1e8 - 1} ]; + const tags = [ + ['foo'], + ['baz'], + ['baz'] + ]; + await hexo.init(); - await Post.insert(posts); + const output = await Post.insert(posts); + await Promise.each(tags, (tags, i) => output[i].setTags(tags)); await hexo.locals.invalidate(); listPosts(); @@ -48,6 +56,7 @@ describe('Console list', () => { sinonAssert.calledWithMatch(logStub, posts[i].source); sinonAssert.calledWithMatch(logStub, posts[i].slug); sinonAssert.calledWithMatch(logStub, posts[i].title); + sinonAssert.calledWithMatch(logStub, tags[i][0]); } }); }); diff --git a/test/scripts/console/list_route.js b/test/scripts/console/list_route.js index 0cbf86996f..3169544ad4 100644 --- a/test/scripts/console/list_route.js +++ b/test/scripts/console/list_route.js @@ -27,5 +27,15 @@ describe('Console list', () => { listRoutes(); sinonAssert.calledWithMatch(logStub, 'Total: 1'); + route.remove('test'); + }); + + it('route with nodes', async () => { + route.set('test0/test1', 'foo'); + + listRoutes(); + sinonAssert.calledWithMatch(logStub, 'Total: 1'); + sinonAssert.calledWithMatch(logStub, '└─┬ test0'); + sinonAssert.calledWithMatch(logStub, ' └── test1'); }); }); diff --git a/test/scripts/console/new.js b/test/scripts/console/new.js index 16e93f4b69..4fd68eaf62 100644 --- a/test/scripts/console/new.js +++ b/test/scripts/console/new.js @@ -5,6 +5,7 @@ const moment = require('moment'); const { join } = require('path'); const Promise = require('bluebird'); const { useFakeTimers } = require('sinon'); +const { spy } = require('sinon'); describe('new', () => { const Hexo = require('../../../dist/hexo'); @@ -39,6 +40,16 @@ describe('new', () => { return rmdir(hexo.base_dir); }); + it('no args', async () => { + hexo.call = spy(); + await n({ + _: [] + }); + hexo.call.calledOnce.should.be.true; + hexo.call.args[0][0].should.eql('help'); + hexo.call.args[0][1]._[0].should.eql('new'); + }); + it('title', async () => { const date = moment(now); const path = join(hexo.source_dir, '_posts', 'Hello-World.md'); @@ -157,6 +168,26 @@ describe('new', () => { await unlink(path); }); + it('without _', async () => { + const date = moment(now); + const path = join(hexo.source_dir, '_posts', 'bar.md'); + const body = [ + 'title: bar', + 'date: ' + date.format('YYYY-MM-DD HH:mm:ss'), + 'tags:', + '---' + ].join('\n') + '\n'; + + await n({ + _: [], + path: 'bar' + }); + const content = await readFile(path); + content.should.eql(body); + + await unlink(path); + }); + it('rename if target existed', async () => { const path = join(hexo.source_dir, '_posts', 'Hello-World-1.md'); diff --git a/test/scripts/helpers/paginator.js b/test/scripts/helpers/paginator.js index 04826e453b..fe46d685c8 100644 --- a/test/scripts/helpers/paginator.js +++ b/test/scripts/helpers/paginator.js @@ -341,4 +341,22 @@ describe('paginator', () => { '' ].join('')); }); + + it('force_prev_next - 2', () => { + const result = paginator({ + current: 1, + prev_next: false, + force_prev_next: true + }); + + result.should.eql([ + '', + '1', + '2', + '3', + '', + '10', + '' + ].join('')); + }); }); diff --git a/test/scripts/processors/asset.js b/test/scripts/processors/asset.js index 1b2c1a10b9..ed878e4084 100644 --- a/test/scripts/processors/asset.js +++ b/test/scripts/processors/asset.js @@ -188,6 +188,19 @@ describe('asset', () => { should.not.exist(Asset.findById(id)); }); + it('asset - type: delete - not exist', async () => { + const file = newFile({ + path: 'foo.jpg', + type: 'delete', + renderable: false + }); + + const id = 'source/' + file.path; + await process(file); + + should.not.exist(Asset.findById(id)); + }); + it('page - type: create', async () => { const body = [ 'title: "Hello world"', @@ -249,6 +262,25 @@ describe('asset', () => { ]); }); + it('page - type: skip', async () => { + const file = newFile({ + path: 'hello.njk', + type: 'skip', + renderable: true + }); + + await Page.insert({ + source: file.path, + path: 'hello.html' + }); + const page = Page.findOne({source: file.path}); + await process(file); + should.exist(page); + await Promise.all([ + page.remove() + ]); + }); + it('page - type: delete', async () => { const file = newFile({ path: 'hello.njk', @@ -264,6 +296,17 @@ describe('asset', () => { should.not.exist(Page.findOne({ source: file.path })); }); + it('page - type: delete - not exist', async () => { + const file = newFile({ + path: 'hello.njk', + type: 'delete', + renderable: true + }); + + await process(file); + should.not.exist(Page.findOne({ source: file.path })); + }); + it('page - use the status of the source file if date not set', async () => { const file = newFile({ path: 'hello.njk', diff --git a/test/scripts/processors/data.js b/test/scripts/processors/data.js index d2d1345dc1..ef5493e469 100644 --- a/test/scripts/processors/data.js +++ b/test/scripts/processors/data.js @@ -128,6 +128,22 @@ describe('data', () => { unlink(file.source); }); + it('type: skip', async () => { + const file = newFile({ + path: 'users.yml', + type: 'skip' + }); + + await Data.insert({ + _id: 'users', + data: {foo: 'bar'} + }); + const data = Data.findById('users'); + await process(file); + should.exist(data); + data.remove(); + }); + it('type: delete', async () => { const file = newFile({ path: 'users.yml', @@ -141,4 +157,15 @@ describe('data', () => { await process(file); should.not.exist(Data.findById('users')); }); + + it('type: delete - not exist', async () => { + const file = newFile({ + path: 'users.yml', + type: 'delete' + }); + + await process(file); + should.not.exist(Data.findById('users')); + }); + }); diff --git a/test/scripts/processors/post.js b/test/scripts/processors/post.js index 8d653f61ca..7530da34c4 100644 --- a/test/scripts/processors/post.js +++ b/test/scripts/processors/post.js @@ -250,6 +250,31 @@ describe('post', () => { Post.removeById(postId); }); + it('asset - type: delete - not exist', async () => { + hexo.config.post_asset_folder = true; + + const file = newFile({ + path: 'foo/bar.jpg', + published: true, + type: 'delete', + renderable: false + }); + + const id = 'source/' + file.path; + + const post = await Post.insert({ + source: '_posts/foo.html', + slug: 'foo' + }); + const postId = post._id; + + await process(file); + should.not.exist(PostAsset.findById(id)); + + Post.removeById(postId); + }); + + it('asset - skip if can\'t find a matching post', async () => { hexo.config.post_asset_folder = true; @@ -358,6 +383,36 @@ describe('post', () => { ]); }); + it('post - type: skip', async () => { + const file = newFile({ + path: 'foo.html', + published: true, + type: 'skip', + renderable: true + }); + + await Post.insert({ + source: file.path, + slug: 'foo' + }); + await process(file); + const post = Post.findOne({ source: file.path }); + should.exist(post); + post.remove(); + }); + + it('post - type: delete - not exist', async () => { + const file = newFile({ + path: 'foo.html', + published: true, + type: 'delete', + renderable: true + }); + + await process(file); + should.not.exist(Post.findOne({ source: file.path })); + }); + it('post - type: delete', async () => { const file = newFile({ path: 'foo.html', @@ -374,6 +429,18 @@ describe('post', () => { should.not.exist(Post.findOne({ source: file.path })); }); + it('post - type: delete - not exist', async () => { + const file = newFile({ + path: 'foo.html', + published: true, + type: 'delete', + renderable: true + }); + + await process(file); + should.not.exist(Post.findOne({ source: file.path })); + }); + it('post - parse file name', async () => { const body = [ 'title: "Hello world"', diff --git a/test/scripts/renderers/nunjucks.js b/test/scripts/renderers/nunjucks.js index a875211caf..4159f424b0 100644 --- a/test/scripts/renderers/nunjucks.js +++ b/test/scripts/renderers/nunjucks.js @@ -123,6 +123,14 @@ describe('nunjucks', () => { r({ text: forLoop }, data).should.eql('123'); }); + it('toarray other case', () => { + const data = { + arr: 1 + }; + + r({ text: forLoop }, data).should.eql(''); + }); + it('safedump undefined', () => { const text = [ '{{ items | safedump }}' From c9ad8c64f22489edeb3c113a83f4c4d1e0a3dde5 Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Sat, 3 Jun 2023 20:53:27 +0800 Subject: [PATCH 18/29] feat: add url_for and full_url_for tag plugins (#5198) * feat: add url_for and full_url_for tag plugins * style: fix lint --- lib/plugins/tag/full_url_for.ts | 17 +++++ lib/plugins/tag/index.ts | 3 + lib/plugins/tag/url_for.ts | 17 +++++ test/scripts/tags/full_url_for.js | 62 +++++++++++++++ test/scripts/tags/index.js | 2 + test/scripts/tags/url_for.js | 121 ++++++++++++++++++++++++++++++ 6 files changed, 222 insertions(+) create mode 100644 lib/plugins/tag/full_url_for.ts create mode 100644 lib/plugins/tag/url_for.ts create mode 100644 test/scripts/tags/full_url_for.js create mode 100644 test/scripts/tags/url_for.js diff --git a/lib/plugins/tag/full_url_for.ts b/lib/plugins/tag/full_url_for.ts new file mode 100644 index 0000000000..6dd2ff76b8 --- /dev/null +++ b/lib/plugins/tag/full_url_for.ts @@ -0,0 +1,17 @@ +import { full_url_for, htmlTag } from 'hexo-util'; + +/** + * Full url for tag + * + * Syntax: + * {% full_url_for text path %} + */ +export = ctx => { + return function fullUrlForTag([text, path]) { + const url = full_url_for.call(ctx, path); + const attrs = { + href: url + }; + return htmlTag('a', attrs, text); + }; +}; diff --git a/lib/plugins/tag/index.ts b/lib/plugins/tag/index.ts index af7b513211..b2306d36e4 100644 --- a/lib/plugins/tag/index.ts +++ b/lib/plugins/tag/index.ts @@ -44,6 +44,9 @@ export default (ctx: Hexo) => { tag.register('asset_image', assetImg); tag.register('pullquote', require('./pullquote')(ctx), true); + + tag.register('url_for', require('./url_for')(ctx)); + tag.register('full_url_for', require('./full_url_for')(ctx)); }; // Use WeakMap to track different ctx (in case there is any) diff --git a/lib/plugins/tag/url_for.ts b/lib/plugins/tag/url_for.ts new file mode 100644 index 0000000000..6fb3750886 --- /dev/null +++ b/lib/plugins/tag/url_for.ts @@ -0,0 +1,17 @@ +import { url_for, htmlTag } from 'hexo-util'; + +/** + * Url for tag + * + * Syntax: + * {% url_for text path [relative] %} + */ +export = ctx => { + return function urlForTag([text, path, relative]) { + const url = url_for.call(ctx, path, relative ? { relative: relative !== 'false' } : undefined); + const attrs = { + href: url + }; + return htmlTag('a', attrs, text); + }; +}; diff --git a/test/scripts/tags/full_url_for.js b/test/scripts/tags/full_url_for.js new file mode 100644 index 0000000000..ea01912392 --- /dev/null +++ b/test/scripts/tags/full_url_for.js @@ -0,0 +1,62 @@ +'use strict'; + +const cheerio = require('cheerio'); + +describe('full_url_for', () => { + const ctx = { + config: { url: 'https://example.com' } + }; + + const fullUrlForTag = require('../../../dist/plugins/tag/full_url_for')(ctx); + const fullUrlFor = args => fullUrlForTag(args.split(' ')); + + it('no path input', () => { + const $ = cheerio.load(fullUrlFor('nopath')); + $('a').attr('href').should.eql(ctx.config.url + '/'); + $('a').html().should.eql('nopath'); + }); + + it('internal url', () => { + let $ = cheerio.load(fullUrlFor('index index.html')); + $('a').attr('href').should.eql(ctx.config.url + '/index.html'); + $('a').html().should.eql('index'); + + $ = cheerio.load(fullUrlFor('index /')); + $('a').attr('href').should.eql(ctx.config.url + '/'); + $('a').html().should.eql('index'); + + $ = cheerio.load(fullUrlFor('index /index.html')); + $('a').attr('href').should.eql(ctx.config.url + '/index.html'); + $('a').html().should.eql('index'); + }); + + it('internel url (pretty_urls.trailing_index disabled)', () => { + ctx.config.pretty_urls = { trailing_index: false }; + let $ = cheerio.load(fullUrlFor('index index.html')); + $('a').attr('href').should.eql(ctx.config.url + '/'); + $('a').html().should.eql('index'); + + $ = cheerio.load(fullUrlFor('index /index.html')); + $('a').attr('href').should.eql(ctx.config.url + '/'); + $('a').html().should.eql('index'); + }); + + it('external url', () => { + [ + 'https://hexo.io/', + '//google.com/', + // 'index.html' in external link should not be removed + '//google.com/index.html' + ].forEach(url => { + const $ = cheerio.load(fullUrlFor(`external ${url}`)); + $('a').attr('href').should.eql(url); + $('a').html().should.eql('external'); + }); + }); + + it('only hash', () => { + const $ = cheerio.load(fullUrlFor('hash #test')); + $('a').attr('href').should.eql(ctx.config.url + '/#test'); + $('a').html().should.eql('hash'); + }); +}); diff --git a/test/scripts/tags/index.js b/test/scripts/tags/index.js index 7ff000647c..21dc58a9b3 100644 --- a/test/scripts/tags/index.js +++ b/test/scripts/tags/index.js @@ -6,6 +6,7 @@ describe('Tags', () => { require('./asset_path'); require('./blockquote'); require('./code'); + require('./full_url_for'); require('./iframe'); require('./img'); require('./include_code'); @@ -13,4 +14,5 @@ describe('Tags', () => { require('./post_link'); require('./post_path'); require('./pullquote'); + require('./url_for'); }); diff --git a/test/scripts/tags/url_for.js b/test/scripts/tags/url_for.js new file mode 100644 index 0000000000..1b905df59a --- /dev/null +++ b/test/scripts/tags/url_for.js @@ -0,0 +1,121 @@ +'use strict'; + +const cheerio = require('cheerio'); + +describe('url_for', () => { + const ctx = { + config: { url: 'https://example.com' } + }; + + const urlForTag = require('../../../dist/plugins/tag/url_for')(ctx); + const urlFor = args => urlForTag(args.split(' ')); + + it('should encode path', () => { + ctx.config.root = '/'; + let $ = cheerio.load(urlFor('foo fôo.html')); + $('a').attr('href').should.eql('/f%C3%B4o.html'); + $('a').html().should.eql('foo'); + + ctx.config.root = '/fôo/'; + $ = cheerio.load(urlFor('foo bár.html')); + $('a').attr('href').should.eql('/f%C3%B4o/b%C3%A1r.html'); + $('a').html().should.eql('foo'); + }); + + it('internal url (relative off)', () => { + ctx.config.root = '/'; + let $ = cheerio.load(urlFor('index index.html')); + $('a').attr('href').should.eql('/index.html'); + $('a').html().should.eql('index'); + + $ = cheerio.load(urlFor('index /')); + $('a').attr('href').should.eql('/'); + $('a').html().should.eql('index'); + + $ = cheerio.load(urlFor('index /index.html')); + $('a').attr('href').should.eql('/index.html'); + $('a').html().should.eql('index'); + + ctx.config.root = '/blog/'; + $ = cheerio.load(urlFor('index index.html')); + $('a').attr('href').should.eql('/blog/index.html'); + $('a').html().should.eql('index'); + + $ = cheerio.load(urlFor('index /')); + $('a').attr('href').should.eql('/blog/'); + $('a').html().should.eql('index'); + + $ = cheerio.load(urlFor('index /index.html')); + $('a').attr('href').should.eql('/blog/index.html'); + $('a').html().should.eql('index'); + }); + + it('internal url (relative on)', () => { + ctx.config.relative_link = true; + ctx.config.root = '/'; + + ctx.path = ''; + let $ = cheerio.load(urlFor('index index.html')); + $('a').attr('href').should.eql('index.html'); + $('a').html().should.eql('index'); + + ctx.path = 'foo/bar/'; + $ = cheerio.load(urlFor('index index.html')); + $('a').attr('href').should.eql('../../index.html'); + $('a').html().should.eql('index'); + + ctx.config.relative_link = false; + }); + + it('internal url (options.relative)', () => { + ctx.path = ''; + let $ = cheerio.load(urlFor('index index.html true')); + $('a').attr('href').should.eql('index.html'); + $('a').html().should.eql('index'); + + ctx.config.relative_link = true; + $ = cheerio.load(urlFor('index index.html false')); + $('a').attr('href').should.eql('/index.html'); + $('a').html().should.eql('index'); + ctx.config.relative_link = false; + }); + + it('internel url (pretty_urls.trailing_index disabled)', () => { + ctx.config.pretty_urls = { trailing_index: false }; + ctx.path = ''; + ctx.config.root = '/'; + let $ = cheerio.load(urlFor('index index.html')); + $('a').attr('href').should.eql('/'); + $('a').html().should.eql('index'); + $ = cheerio.load(urlFor('index /index.html')); + $('a').attr('href').should.eql('/'); + $('a').html().should.eql('index'); + + ctx.config.root = '/blog/'; + $ = cheerio.load(urlFor('index index.html')); + $('a').attr('href').should.eql('/blog/'); + $('a').html().should.eql('index'); + $ = cheerio.load(urlFor('index /index.html')); + $('a').attr('href').should.eql('/blog/'); + $('a').html().should.eql('index'); + }); + + it('external url', () => { + [ + 'https://hexo.io/', + '//google.com/', + // 'index.html' in external link should not be removed + '//google.com/index.html' + ].forEach(url => { + const $ = cheerio.load(urlFor(`external ${url}`)); + $('a').attr('href').should.eql(url); + $('a').html().should.eql('external'); + }); + }); + + it('only hash', () => { + const $ = cheerio.load(urlFor('hash #test')); + $('a').attr('href').should.eql('#test'); + $('a').html().should.eql('hash'); + }); +}); From 7157e85b6751274a9e9730735af423c574ae0f82 Mon Sep 17 00:00:00 2001 From: Xianwei Pang Date: Fri, 16 Jun 2023 15:07:29 +0800 Subject: [PATCH 19/29] feat: allow top-level await in plugins or scripts (#5228) --- lib/hexo/index.ts | 2 +- test/scripts/hexo/load_plugins.js | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/hexo/index.ts b/lib/hexo/index.ts index 15a0d6403e..93480baab2 100644 --- a/lib/hexo/index.ts +++ b/lib/hexo/index.ts @@ -387,7 +387,7 @@ class Hexo extends EventEmitter { req.extensions = Module._extensions; req.cache = Module._cache; - script = `(function(exports, require, module, __filename, __dirname, hexo){${script}\n});`; + script = `(async function(exports, require, module, __filename, __dirname, hexo){${script}\n});`; const fn = runInThisContext(script, path); diff --git a/test/scripts/hexo/load_plugins.js b/test/scripts/hexo/load_plugins.js index f6f7b44b17..50dd9620b3 100644 --- a/test/scripts/hexo/load_plugins.js +++ b/test/scripts/hexo/load_plugins.js @@ -18,6 +18,18 @@ describe('Load plugins', () => { '}' ].join('\n'); + const asyncScript = [ + 'async function afunc() {', + ' return new Promise(resolve => resolve());', + '}', + 'await afunc()', + 'hexo._script_test = {', + ' filename: __filename,', + ' dirname: __dirname,', + ' module: module,', + ' require: require', + '}' + ].join('\n'); function validate(path) { const result = hexo._script_test; @@ -81,6 +93,19 @@ describe('Load plugins', () => { }); }); + it('load async plugins', () => { + const name = 'hexo-async-plugin-test'; + const path = join(hexo.plugin_dir, name, 'index.js'); + + return Promise.all([ + createPackageFile(name), + fs.writeFile(path, asyncScript) + ]).then(() => loadPlugins(hexo)).then(() => { + validate(path); + return fs.unlink(path); + }); + }); + it('load scoped plugins', () => { const name = '@some-scope/hexo-plugin-test'; const path = join(hexo.plugin_dir, name, 'index.js'); From 3eaafb44fca9a537b4089481a9f4f60f10ab4c2a Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Mon, 10 Jul 2023 01:28:07 +0800 Subject: [PATCH 20/29] fix(moize): helper function not working fine with relative_url (#5217) --- lib/plugins/helper/css.ts | 8 +++++++- lib/plugins/helper/js.ts | 8 +++++++- test/scripts/helpers/css.js | 13 +++++++++++++ test/scripts/helpers/js.js | 13 +++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/lib/plugins/helper/css.ts b/lib/plugins/helper/css.ts index b7a86f5524..74ca0ba357 100644 --- a/lib/plugins/helper/css.ts +++ b/lib/plugins/helper/css.ts @@ -1,9 +1,12 @@ import { htmlTag, url_for } from 'hexo-util'; import moize from 'moize'; +let relative_link = true; function cssHelper(...args) { let result = '\n'; + relative_link = this.config.relative_link; + args.flat(Infinity).forEach(item => { if (typeof item === 'string' || item instanceof String) { let path = item; @@ -23,5 +26,8 @@ function cssHelper(...args) { export = moize(cssHelper, { maxSize: 10, - isDeepEqual: true + isDeepEqual: true, + updateCacheForKey() { + return relative_link; + } }); diff --git a/lib/plugins/helper/js.ts b/lib/plugins/helper/js.ts index 120d1738bb..24ca0fca3d 100644 --- a/lib/plugins/helper/js.ts +++ b/lib/plugins/helper/js.ts @@ -1,9 +1,12 @@ import { htmlTag, url_for } from 'hexo-util'; import moize from 'moize'; +let relative_link = true; function jsHelper(...args) { let result = '\n'; + relative_link = this.config.relative_link; + args.flat(Infinity).forEach(item => { if (typeof item === 'string' || item instanceof String) { let path = item; @@ -23,5 +26,8 @@ function jsHelper(...args) { export = moize(jsHelper, { maxSize: 10, - isDeepEqual: true + isDeepEqual: true, + updateCacheForKey() { + return relative_link; + } }); diff --git a/test/scripts/helpers/css.js b/test/scripts/helpers/css.js index ea68001273..6241ff93fd 100644 --- a/test/scripts/helpers/css.js +++ b/test/scripts/helpers/css.js @@ -73,4 +73,17 @@ describe('css', () => { assertResult(css([{href: '/aaa.css', bbb: 'ccc'}, {href: '/ddd.css', eee: 'fff'}]), [{href: '/aaa.css', bbb: 'ccc'}, {href: '/ddd.css', eee: 'fff'}]); }); + + it('relative link', () => { + ctx.config.relative_link = true; + ctx.config.root = '/'; + + ctx.path = ''; + assertResult(css('style'), 'style.css'); + + ctx.path = 'foo/bar/'; + assertResult(css('style'), '../../style.css'); + + ctx.config.relative_link = false; + }); }); diff --git a/test/scripts/helpers/js.js b/test/scripts/helpers/js.js index 5dbc4a16d4..22a23805b1 100644 --- a/test/scripts/helpers/js.js +++ b/test/scripts/helpers/js.js @@ -82,4 +82,17 @@ describe('js', () => { assertResult(js({src: '/foo.js', 'async': true}), {src: '/foo.js', 'async': true}); assertResult(js({src: '/bar.js', 'defer': true}), {src: '/bar.js', 'defer': true}); }); + + it('relative link', () => { + ctx.config.relative_link = true; + ctx.config.root = '/'; + + ctx.path = ''; + assertResult(js('script'), 'script.js'); + + ctx.path = 'foo/bar/'; + assertResult(js('script'), '../../script.js'); + + ctx.config.relative_link = false; + }); }); From 04bc704d9479912c36208ffd9daa95677b08c1af Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Mon, 10 Jul 2023 01:29:39 +0800 Subject: [PATCH 21/29] test: improve coverage (#5223) --- test/scripts/box/box.js | 10 ++++++ test/scripts/console/generate.js | 17 ++++++++++ test/scripts/console/list.js | 19 ++++++++++- test/scripts/extend/processor.js | 5 +++ test/scripts/extend/tag.js | 12 ++++--- test/scripts/generators/asset.js | 26 +++++++++++++++ test/scripts/hexo/multi_config_path.js | 8 +++++ test/scripts/hexo/post.js | 13 +++++++- test/scripts/hexo/render.js | 13 ++++++++ test/scripts/processors/asset.js | 41 +++++++++++++++++++++++ test/scripts/processors/post.js | 44 +++++++++++++++++++++++++ test/scripts/theme_processors/source.js | 12 +++++++ 12 files changed, 213 insertions(+), 7 deletions(-) diff --git a/test/scripts/box/box.js b/test/scripts/box/box.js index 9271a2296b..71548cceeb 100644 --- a/test/scripts/box/box.js +++ b/test/scripts/box/box.js @@ -262,6 +262,16 @@ describe('Box', () => { await rmdir(box.base); }); + it('process() - error ignore - 1', async () => { + const box = newBox('test', { ignore: [null] }); + box.options.ignored.should.eql([]); + }); + + it('process() - error ignore - 2', async () => { + const box = newBox('test', { ignore: [111] }); + box.options.ignored.should.eql([]); + }); + it('process() - skip files if they match a glob epression in ignore', async () => { const box = newBox('test', { ignore: '**/ignore_me' }); const data = {}; diff --git a/test/scripts/console/generate.js b/test/scripts/console/generate.js index 7ac2bae2d4..d4b39ef337 100644 --- a/test/scripts/console/generate.js +++ b/test/scripts/console/generate.js @@ -55,6 +55,23 @@ describe('generate', () => { it('default', () => testGenerate()); + it('public_dir is not a directory', async () => { + await Promise.all([ + // Add some source files + writeFile(join(hexo.source_dir, 'test.txt'), 'test'), + // Add some files to public folder + writeFile(join(hexo.public_dir, 'foo.txt'), 'foo') + ]); + const old = hexo.public_dir; + hexo.public_dir = join(hexo.public_dir, 'foo.txt'); + try { + await generate(); + } catch (e) { + e.message.split(' ').slice(1).join(' ').should.eql('is not a directory'); + } + hexo.public_dir = old; + }); + it('write file if not exist', async () => { const src = join(hexo.source_dir, 'test.txt'); const dest = join(hexo.public_dir, 'test.txt'); diff --git a/test/scripts/console/list.js b/test/scripts/console/list.js index 530a83ffbd..124274888d 100644 --- a/test/scripts/console/list.js +++ b/test/scripts/console/list.js @@ -1,6 +1,7 @@ 'use strict'; -const { spy } = require('sinon'); +const { spy, stub, assert: sinonAssert } = require('sinon'); +const Promise = require('bluebird'); describe('Console list', () => { const Hexo = require('../../../dist/hexo'); @@ -18,6 +19,22 @@ describe('Console list', () => { hexo.call.args[0][1]._[0].should.eql('list'); }); + it('has args', async () => { + const logStub = stub(console, 'log'); + + hexo.load = () => Promise.resolve(); + + const list = require('../../../dist/plugins/console/list').bind(hexo); + + await list({ _: ['page'] }); + + sinonAssert.calledWithMatch(logStub, 'Date'); + sinonAssert.calledWithMatch(logStub, 'Title'); + sinonAssert.calledWithMatch(logStub, 'Path'); + sinonAssert.calledWithMatch(logStub, 'No pages.'); + logStub.restore(); + }); + it('list type not found', () => { hexo.call = spy(); diff --git a/test/scripts/extend/processor.js b/test/scripts/extend/processor.js index eddae6d80b..1d9cb12407 100644 --- a/test/scripts/extend/processor.js +++ b/test/scripts/extend/processor.js @@ -16,6 +16,11 @@ describe('Processor', () => { p.list()[1].should.exist; + // more than one arg + p.register((a, b) => {}); + + p.list()[1].should.exist; + // no fn should.throw(() => p.register(), TypeError, 'fn must be a function'); }); diff --git a/test/scripts/extend/tag.js b/test/scripts/extend/tag.js index e46c7a3cb2..8f10573af1 100644 --- a/test/scripts/extend/tag.js +++ b/test/scripts/extend/tag.js @@ -1,7 +1,5 @@ 'use strict'; -const { spy } = require('sinon'); - describe('Tag', () => { const Tag = require('../../../dist/extend/tag'); const tag = new Tag(); @@ -164,13 +162,17 @@ describe('Tag', () => { it('render() - callback', () => { const tag = new Tag(); - const callback = spy(); + // spy() is not a function + let spy = false; + const callback = () => { + spy = true; + }; tag.register('test', () => 'foo'); - return tag.render('{% test %}', callback()).then(result => { + return tag.render('{% test %}', callback).then(result => { result.should.eql('foo'); - callback.calledOnce.should.be.true; + spy.should.eql(true); }); }); }); diff --git a/test/scripts/generators/asset.js b/test/scripts/generators/asset.js index 0486dc0305..3e898cc671 100644 --- a/test/scripts/generators/asset.js +++ b/test/scripts/generators/asset.js @@ -3,6 +3,7 @@ const { join } = require('path'); const { mkdirs, rmdir, unlink, writeFile } = require('hexo-fs'); const testUtil = require('../../util'); +const { spy } = require('sinon'); describe('asset', () => { const Hexo = require('../../../dist/hexo'); @@ -44,6 +45,31 @@ describe('asset', () => { ]); }); + it('renderable - error', async () => { + const logSpy = spy(); + hexo.log.error = logSpy; + const path = 'test.yml'; + const source = join(hexo.base_dir, path); + const content = 'foo: :'; + + await Promise.all([ + Asset.insert({_id: path, path}), + writeFile(source, content) + ]); + const data = await generator(hexo.locals); + data[0].path.should.eql('test.json'); + data[0].data.modified.should.be.true; + await data[0].data.data(); + logSpy.called.should.be.true; + + logSpy.args[0][1].should.contains('Asset render failed: %s'); + logSpy.args[0][2].should.contains('test.json'); + await Promise.all([ + Asset.removeById(path), + unlink(source) + ]); + }); + it('not renderable', async () => { const path = 'test.txt'; const source = join(hexo.base_dir, path); diff --git a/test/scripts/hexo/multi_config_path.js b/test/scripts/hexo/multi_config_path.js index 7cc486657d..3d6cd423b7 100644 --- a/test/scripts/hexo/multi_config_path.js +++ b/test/scripts/hexo/multi_config_path.js @@ -129,6 +129,8 @@ describe('config flag handling', () => { fs.writeFileSync(base + 'test2.yml', testYaml2); fs.writeFileSync(base + 'test1.json', testJson1); fs.writeFileSync(base + 'test2.json', testJson2); + // not supported type + fs.writeFileSync(base + 'test1.xml', ''); fs.writeFileSync('/tmp/test3.json', testJson3); }); @@ -147,6 +149,12 @@ describe('config flag handling', () => { hexo.log.reader[0].msg.should.eql('No config file entered.'); }); + it('not supported type', () => { + mcp(base, 'test1.xml,test1.json').should.equal(base + '_multiconfig.yml'); + hexo.log.reader[0].type.should.eql('warning'); + hexo.log.reader[0].msg.should.eql('Config file test1.xml not supported type.'); + }); + it('1 file', () => { mcp(base, 'test1.yml').should.eql( pathFn.resolve(base + 'test1.yml')); diff --git a/test/scripts/hexo/post.js b/test/scripts/hexo/post.js index d2d3bbaa41..6dd792f617 100644 --- a/test/scripts/hexo/post.js +++ b/test/scripts/hexo/post.js @@ -903,7 +903,8 @@ describe('Post', () => { ].join('\n'); const data = await post.render(null, { - content + content, + engine: 'markdown' }); data.content.trim().should.eql([ '

test1

', @@ -913,6 +914,16 @@ describe('Post', () => { ].join('\n')); }); + it('render() - swig comments', async () => { + const content = '{# blockquote #}'; + + const data = await post.render(null, { + content, + engine: 'markdown' + }); + data.content.trim().should.eql(''); + }); + it('render() - shouln\'t break curly brackets', async () => { hexo.config.syntax_highlighter = 'prismjs'; diff --git a/test/scripts/hexo/render.js b/test/scripts/hexo/render.js index 5dc5a8c6e6..5ebb6f16db 100644 --- a/test/scripts/hexo/render.js +++ b/test/scripts/hexo/render.js @@ -104,6 +104,15 @@ describe('Render', () => { } }); + it('render() - null path and text', async () => { + try { + await hexo.render.render({text: null, engine: null}); + should.fail('Return value must be rejected'); + } catch (err) { + err.message.should.eql('No input file or string!'); + } + }); + it('render() - options', async () => { const result = await hexo.render.render({ text: [ @@ -228,6 +237,10 @@ describe('Render', () => { should.throw(() => hexo.render.renderSync(), 'No input file or string!'); }); + it('renderSync() - null path and text', () => { + should.throw(() => hexo.render.renderSync({text: null, engine: null}), 'No input file or string!'); + }); + it('renderSync() - options', () => { const result = hexo.render.renderSync({ text: [ diff --git a/test/scripts/processors/asset.js b/test/scripts/processors/asset.js index ed878e4084..2a268714c3 100644 --- a/test/scripts/processors/asset.js +++ b/test/scripts/processors/asset.js @@ -2,6 +2,7 @@ const { dirname, join } = require('path'); const { mkdirs, rmdir, stat, unlink, writeFile } = require('hexo-fs'); +const { spy } = require('sinon'); const dateFormat = 'YYYY-MM-DD HH:mm:ss'; @@ -235,6 +236,46 @@ describe('asset', () => { ]); }); + it('page - type: create - exist', async () => { + const logSpy = spy(); + hexo.log.warn = logSpy; + + const body = [ + 'title: "Hello world"', + 'date: 2006-01-02 15:04:05', + 'updated: 2014-12-13 01:02:03', + '---', + 'The quick brown fox jumps over the lazy dog' + ].join('\n'); + + const file = newFile({ + path: 'hello.njk', + type: 'create', + renderable: true + }); + + await writeFile(file.source, body); + await process(file); + await process(file); + + const page = Page.findOne({ source: file.path }); + page.title.should.eql('Hello world'); + page.date.format(dateFormat).should.eql('2006-01-02 15:04:05'); + page.updated.format(dateFormat).should.eql('2014-12-13 01:02:03'); + page._content.should.eql('The quick brown fox jumps over the lazy dog'); + page.source.should.eql(file.path); + page.raw.should.eql(body); + page.path.should.eql('hello.html'); + page.layout.should.eql('page'); + + logSpy.called.should.be.true; + logSpy.args[0][0].should.contains('Trying to "create" \x1B[35mhello.njk\x1B[39m, but the file already exists!'); + await Promise.all([ + page.remove(), + unlink(file.source) + ]); + }); + it('page - type: update', async () => { const body = [ 'title: "Hello world"', diff --git a/test/scripts/processors/post.js b/test/scripts/processors/post.js index 7530da34c4..9cb00b3ac7 100644 --- a/test/scripts/processors/post.js +++ b/test/scripts/processors/post.js @@ -1073,6 +1073,50 @@ describe('post', () => { ]); }); + it('post - delete existing draft assets if draft posts are hidden', async () => { + hexo.config.post_asset_folder = true; + + const body = [ + 'title: "Hello world"', + 'published: false', + '---' + ].join('\n'); + + const file = newFile({ + path: 'foo.html', + published: true, + type: 'create', + renderable: true + }); + + const assetId = 'source/_posts/foo/bar.jpg'; + const assetPath = join(hexo.base_dir, assetId); + + await Promise.all([ + writeFile(file.source, body), + writeFile(assetPath, '') + ]); + + // drafts disabled - no draft assets should be generated + await process(file); + const post = Post.findOne({ source: file.path }); + await PostAsset.insert({ + _id: 'source/_posts/foo/bar.jpg', + slug: 'bar.jpg', + post: post._id + }); + await process(file); + + post.published.should.be.false; + should.not.exist(PostAsset.findById(assetId)); + + await Promise.all([ + post.remove(), + unlink(file.source), + unlink(assetPath) + ]); + }); + it('post - post_asset_folder disabled', async () => { hexo.config.post_asset_folder = false; diff --git a/test/scripts/theme_processors/source.js b/test/scripts/theme_processors/source.js index 9cf4387e45..b84546e3d0 100644 --- a/test/scripts/theme_processors/source.js +++ b/test/scripts/theme_processors/source.js @@ -136,4 +136,16 @@ describe('source', () => { await process(file); should.not.exist(Asset.findById(id)); }); + + it('type: delete - not -exist', async () => { + const file = newFile({ + path: 'style.css', + type: 'delete' + }); + + const id = 'themes/test/' + file.path; + + await process(file); + should.not.exist(Asset.findById(id)); + }); }); From b3b444d7585920302a0e749614ada57317866a77 Mon Sep 17 00:00:00 2001 From: yoshinorin Date: Tue, 11 Jul 2023 22:39:23 +0900 Subject: [PATCH 22/29] release: `v7.0.0-rc2` (#5238) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 486140b30a..8080a1db88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hexo", - "version": "7.0.0-rc1", + "version": "7.0.0-rc2", "description": "A fast, simple & powerful blog framework, powered by Node.js.", "main": "dist/hexo", "bin": { From 0257bb368032754cccdf649bea3f633e068ea0e3 Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Tue, 25 Jul 2023 22:16:41 +0800 Subject: [PATCH 23/29] fix typo (#5245) --- lib/box/index.ts | 6 +++--- lib/extend/syntax_highlight.ts | 2 +- lib/extend/tag.ts | 6 +++--- lib/hexo/index.ts | 4 ++-- lib/hexo/post.ts | 14 +++++++------- lib/plugins/helper/paginator.ts | 4 ++-- lib/plugins/renderer/nunjucks.ts | 1 - 7 files changed, 18 insertions(+), 19 deletions(-) diff --git a/lib/box/index.ts b/lib/box/index.ts index 5f8978d6fc..a61e08e54e 100644 --- a/lib/box/index.ts +++ b/lib/box/index.ts @@ -280,13 +280,13 @@ function readDirWalker(ctx, base, results, ignore, prefix) { if (err && err.code === 'ENOENT') return null; throw err; }); - const prefixdPath = `${prefix}${path}`; + const prefixPath = `${prefix}${path}`; if (stats) { if (stats.isDirectory()) { - return readDirWalker(ctx, fullpath, results, ignore, `${prefixdPath}/`); + return readDirWalker(ctx, fullpath, results, ignore, `${prefixPath}/`); } if (!isIgnoreMatch(fullpath, ignore)) { - results.push(prefixdPath); + results.push(prefixPath); } } }); diff --git a/lib/extend/syntax_highlight.ts b/lib/extend/syntax_highlight.ts index 1ece414224..419a950f24 100644 --- a/lib/extend/syntax_highlight.ts +++ b/lib/extend/syntax_highlight.ts @@ -5,7 +5,7 @@ export interface HighlightOptions { caption: string | undefined, lines_length: number, - // plulgins/filter/before_post_render/backtick_code_block + // plugins/filter/before_post_render/backtick_code_block firstLineNumber?: string | number // plugins/tag/code.ts diff --git a/lib/extend/tag.ts b/lib/extend/tag.ts index dbebd5bfac..f2fcc3d325 100644 --- a/lib/extend/tag.ts +++ b/lib/extend/tag.ts @@ -182,13 +182,13 @@ const formatNunjucksError = (err, input, source = '') => { if (isNaN(errLine)) return err; // trim useless info from Nunjucks Error - const splited = err.message.split('\n'); + const splitted = err.message.split('\n'); const e = new NunjucksError(); e.name = 'Nunjucks Error'; e.line = errLine; - e.location = splited[0]; - e.type = splited[1].trim(); + e.location = splitted[0]; + e.type = splitted[1].trim(); e.message = getContext(input.split(/\r?\n/), errLine, e.location, e.type).join('\n'); return e; }; diff --git a/lib/hexo/index.ts b/lib/hexo/index.ts index 93480baab2..e8c06b83d4 100644 --- a/lib/hexo/index.ts +++ b/lib/hexo/index.ts @@ -512,7 +512,7 @@ class Hexo extends EventEmitter { }, []); } - _routerReflesh(runningGenerators, useCache) { + _routerRefresh(runningGenerators, useCache) { const { route } = this; const routeList = route.list(); const Locals = this._generateLocals(); @@ -556,7 +556,7 @@ class Hexo extends EventEmitter { // Run before_generate filters return this.execFilter('before_generate', this.locals.get('data'), { context: this }) - .then(() => this._routerReflesh(this._runGenerators(), useCache)).then(() => { + .then(() => this._routerRefresh(this._runGenerators(), useCache)).then(() => { this.emit('generateAfter'); // Run after_generate filters diff --git a/lib/hexo/post.ts b/lib/hexo/post.ts index 6eda66cc90..748d73fd94 100644 --- a/lib/hexo/post.ts +++ b/lib/hexo/post.ts @@ -287,16 +287,16 @@ class Post { _renderScaffold(data) { const { tag } = this.context.extend; - let splited; + let splitted; return this._getScaffold(data.layout).then(scaffold => { - splited = yfmSplit(scaffold); - const jsonMode = splited.separator.startsWith(';'); + splitted = yfmSplit(scaffold); + const jsonMode = splitted.separator.startsWith(';'); const frontMatter = prepareFrontMatter({ ...data }, jsonMode); - return tag.render(splited.data, frontMatter); + return tag.render(splitted.data, frontMatter); }).then(frontMatter => { - const { separator } = splited; + const { separator } = splitted; const jsonMode = separator.startsWith(';'); // Parse front-matter @@ -310,14 +310,14 @@ class Post { let content = ''; // Prepend the separator - if (splited.prefixSeparator) content += `${separator}\n`; + if (splitted.prefixSeparator) content += `${separator}\n`; content += yfmStringify(obj, { mode: jsonMode ? 'json' : '' }); // Concat content - content += splited.content; + content += splitted.content; if (data.content) { content += `\n${data.content}`; diff --git a/lib/plugins/helper/paginator.ts b/lib/plugins/helper/paginator.ts index 83a12ff2c1..8d37c80739 100644 --- a/lib/plugins/helper/paginator.ts +++ b/lib/plugins/helper/paginator.ts @@ -34,7 +34,7 @@ const showAll = (tags, options, ctx) => { } }; -const pagenasionPartShow = (tags, options, ctx) => { +const paginationPartShow = (tags, options, ctx) => { const { current, total, @@ -156,7 +156,7 @@ function paginatorHelper(options: Options = {}) { if (options.show_all) { showAll(tags, options, this); } else { - pagenasionPartShow(tags, options, this); + paginationPartShow(tags, options, this); } // Display the link to the next page diff --git a/lib/plugins/renderer/nunjucks.ts b/lib/plugins/renderer/nunjucks.ts index be6cfc1781..1ba4ba0205 100644 --- a/lib/plugins/renderer/nunjucks.ts +++ b/lib/plugins/renderer/nunjucks.ts @@ -1,4 +1,3 @@ - import nunjucks from 'nunjucks'; import { readFileSync } from 'hexo-fs'; import { dirname } from 'path'; From 99e94cc452693b70cbbe61bfb326fb3072a77cbf Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Thu, 27 Jul 2023 19:42:09 +0800 Subject: [PATCH 24/29] feat(post): remove front-matter property `link` (#5253) --- lib/models/post.ts | 1 - lib/plugins/processor/post.ts | 4 ---- test/scripts/models/post.js | 1 - test/scripts/processors/post.js | 28 +--------------------------- 4 files changed, 1 insertion(+), 33 deletions(-) diff --git a/lib/models/post.ts b/lib/models/post.ts index 60695323ec..56e9f8cf6f 100644 --- a/lib/models/post.ts +++ b/lib/models/post.ts @@ -34,7 +34,6 @@ export = ctx => { source: {type: String, required: true}, slug: {type: String, required: true}, photos: [String], - link: {type: String, default: ''}, raw: {type: String, default: ''}, published: {type: Boolean, default: true}, content: {type: String}, diff --git a/lib/plugins/processor/post.ts b/lib/plugins/processor/post.ts index dca6306e62..e433858084 100644 --- a/lib/plugins/processor/post.ts +++ b/lib/plugins/processor/post.ts @@ -159,10 +159,6 @@ function processPost(ctx, file) { data.photos = [data.photos]; } - if (data.link && !data.title) { - data.title = data.link.replace(/^https?:\/\/|\/$/g, ''); - } - if (data.permalink) { data.__permalink = data.permalink; data.permalink = undefined; diff --git a/test/scripts/models/post.js b/test/scripts/models/post.js index e2bf189da0..ded1dc66be 100644 --- a/test/scripts/models/post.js +++ b/test/scripts/models/post.js @@ -31,7 +31,6 @@ describe('Post', () => { data.comments.should.be.true; data.layout.should.eql('post'); data._content.should.eql(''); - data.link.should.eql(''); data.raw.should.eql(''); data.published.should.be.true; should.not.exist(data.updated); diff --git a/test/scripts/processors/post.js b/test/scripts/processors/post.js index 9cb00b3ac7..1beb68207f 100644 --- a/test/scripts/processors/post.js +++ b/test/scripts/processors/post.js @@ -778,33 +778,7 @@ describe('post', () => { ]); }); - it('post - link without title', async () => { - const body = [ - 'link: https://hexo.io/', - '---' - ].join('\n'); - - const file = newFile({ - path: 'foo.html', - published: true, - type: 'create', - renderable: true - }); - - await writeFile(file.source, body); - await process(file); - const post = Post.findOne({ source: file.path }); - - post.link.should.eql('https://hexo.io/'); - post.title.should.eql('hexo.io'); - - return Promise.all([ - post.remove(), - unlink(file.source) - ]); - }); - - it('post - link without title and link', async () => { + it('post - without title', async () => { const body = ''; const file = newFile({ From 5d8dcecbb2d2e3a2f21c3b20b79393d4cf7ae7cd Mon Sep 17 00:00:00 2001 From: Mimi <1119186082@qq.com> Date: Wed, 2 Aug 2023 00:49:37 +0800 Subject: [PATCH 25/29] Revert "fix(backtick_code): handle empty code blocks (#5206)" (#5257) This reverts commit c62909deb607ea104a74c84e83846ca0b0758221. --- .../before_post_render/backtick_code_block.ts | 2 +- test/scripts/filters/backtick_code_block.js | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/lib/plugins/filter/before_post_render/backtick_code_block.ts b/lib/plugins/filter/before_post_render/backtick_code_block.ts index 802ed7edd3..b9df3e60f2 100644 --- a/lib/plugins/filter/before_post_render/backtick_code_block.ts +++ b/lib/plugins/filter/before_post_render/backtick_code_block.ts @@ -1,4 +1,4 @@ -const rBacktick = /^((?:[^\S\r\n]*>){0,3}[^\S\r\n]*)(`{3,}|~{3,})[^\S\r\n]*((?:.*?[^`\s])?)[^\S\r\n]*\n((?:[\s\S]*?\n)*?)(?:(?:[^\S\r\n]*>){0,3}[^\S\r\n]*)\2[^\S\r\n]?(\n+|$)/gm; +const rBacktick = /^((?:[^\S\r\n]*>){0,3}[^\S\r\n]*)(`{3,}|~{3,})[^\S\r\n]*((?:.*?[^`\s])?)[^\S\r\n]*\n((?:[\s\S]*?\n)?)(?:(?:[^\S\r\n]*>){0,3}[^\S\r\n]*)\2[^\S\r\n]?(\n+|$)/gm; const rAllOptions = /([^\s]+)\s+(.+?)\s+(https?:\/\/\S+|\/\S+)\s*(.+)?/; const rLangCaption = /([^\s]+)\s*(.+)?/; diff --git a/test/scripts/filters/backtick_code_block.js b/test/scripts/filters/backtick_code_block.js index b195d76a8e..5c75bbccdb 100644 --- a/test/scripts/filters/backtick_code_block.js +++ b/test/scripts/filters/backtick_code_block.js @@ -650,19 +650,5 @@ describe('Backtick code block', () => { codeBlock(data); data.content.should.eql('' + expected + ''); }); - - it('handle empty code block', () => { - const data = { - content: [ - '``` js', - '```', - '# New line', - '``` js', - '```' - ].join('\n') - }; - codeBlock(data); - data.content.match(//g).length.should.eql(2); - }); }); }); From 35ceaae7a57b366744857b52f8bfa08070930d1d Mon Sep 17 00:00:00 2001 From: D-Sketon <2055272094@qq.com> Date: Wed, 2 Aug 2023 00:50:25 +0800 Subject: [PATCH 26/29] fix(post): skip_render not working in post_asset_folder (#5258) --- lib/plugins/processor/post.ts | 6 ++- test/scripts/processors/post.js | 72 +++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/lib/plugins/processor/post.ts b/lib/plugins/processor/post.ts index e433858084..9c61a561b8 100644 --- a/lib/plugins/processor/post.ts +++ b/lib/plugins/processor/post.ts @@ -217,7 +217,9 @@ function scanAssetDir(ctx, post) { const assetDir = post.asset_dir; const baseDir = ctx.base_dir; + const sourceDir = ctx.config.source_dir; const baseDirLength = baseDir.length; + const sourceDirLength = sourceDir.length; const PostAsset = ctx.model('PostAsset'); return stat(assetDir).then(stats => { @@ -229,6 +231,7 @@ function scanAssetDir(ctx, post) { throw err; }).filter(item => !isExcludedFile(item, ctx.config)).map(item => { const id = join(assetDir, item).substring(baseDirLength).replace(/\\/g, '/'); + const renderablePath = id.substring(sourceDirLength + 1); const asset = PostAsset.findById(id); if (shouldSkipAsset(ctx, post, asset)) return undefined; @@ -237,7 +240,8 @@ function scanAssetDir(ctx, post) { _id: id, post: post._id, slug: item, - modified: true + modified: true, + renderable: ctx.render.isRenderable(renderablePath) && !isMatch(renderablePath, ctx.config.skip_render) }); }); } diff --git a/test/scripts/processors/post.js b/test/scripts/processors/post.js index 1beb68207f..fea2563d62 100644 --- a/test/scripts/processors/post.js +++ b/test/scripts/processors/post.js @@ -1256,4 +1256,76 @@ describe('post', () => { unlink(file.source) ]); }); + + it('asset - post - common render', async () => { + hexo.config.post_asset_folder = true; + + const file = newFile({ + path: 'foo.md', + published: true, + type: 'create', + renderable: true + }); + + const assetFile = newFile({ + path: 'foo/test.yml', + published: true, + type: 'create' + }); + + await Promise.all([ + writeFile(file.source, 'test'), + writeFile(assetFile.source, 'test') + ]); + await process(file); + const id = 'source/' + assetFile.path; + const post = Post.findOne({ source: file.path }); + PostAsset.findById(id).renderable.should.be.true; + + hexo.config.post_asset_folder = false; + + return Promise.all([ + unlink(file.source), + unlink(assetFile.source), + post.remove(), + PostAsset.removeById(id) + ]); + }); + + it('asset - post - skip render', async () => { + hexo.config.post_asset_folder = true; + hexo.config.skip_render = '**.yml'; + + const file = newFile({ + path: 'foo.md', + published: true, + type: 'create', + renderable: true + }); + + const assetFile = newFile({ + path: 'foo/test.yml', + published: true, + type: 'create' + }); + + await Promise.all([ + writeFile(file.source, 'test'), + writeFile(assetFile.source, 'test') + ]); + await process(file); + const id = 'source/' + assetFile.path; + const post = Post.findOne({ source: file.path }); + PostAsset.findById(id).renderable.should.be.false; + + hexo.config.post_asset_folder = false; + hexo.config.skip_render = ''; + + return Promise.all([ + unlink(file.source), + unlink(assetFile.source), + post.remove(), + PostAsset.removeById(id) + ]); + }); }); From 24a7b61942a122d8f5f8886dcd03a2e9e9e8ad59 Mon Sep 17 00:00:00 2001 From: Dimas Lanjaka Date: Thu, 10 Aug 2023 17:04:43 +0700 Subject: [PATCH 27/29] feat: define global variable hexo (#5242) useful for plugin written in typescript or let IDE detecting it --- lib/hexo/index.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/hexo/index.ts b/lib/hexo/index.ts index e8c06b83d4..21c14183fb 100644 --- a/lib/hexo/index.ts +++ b/lib/hexo/index.ts @@ -598,4 +598,11 @@ Hexo.prototype.core_dir = Hexo.core_dir; Hexo.version = version; Hexo.prototype.version = Hexo.version; +// define global variable +// this useful for plugin written in typescript +declare global { + // eslint-disable-next-line one-var + const hexo: Hexo; +} + export = Hexo; From d29d774c100e373b937d5329932506143a9cb8eb Mon Sep 17 00:00:00 2001 From: Uiolee <22849383+uiolee@users.noreply.github.com> Date: Fri, 1 Sep 2023 00:51:45 +0800 Subject: [PATCH 28/29] chore(lint-staged): remove `git-exec-and-restage` (#5281) --- .lintstagedrc | 3 --- .lintstagedrc.json | 4 ++++ package.json | 5 ++--- 3 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 .lintstagedrc create mode 100644 .lintstagedrc.json diff --git a/.lintstagedrc b/.lintstagedrc deleted file mode 100644 index 66886867d5..0000000000 --- a/.lintstagedrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "*.js": "git-exec-and-restage eslint --fix --" -} diff --git a/.lintstagedrc.json b/.lintstagedrc.json new file mode 100644 index 0000000000..6953073375 --- /dev/null +++ b/.lintstagedrc.json @@ -0,0 +1,4 @@ +{ + "*.js": "eslint --fix", + "*.ts": "eslint --fix" +} diff --git a/package.json b/package.json index 8080a1db88..cc7f6a65e9 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,6 @@ }, "devDependencies": { "0x": "^5.1.2", - "@easyops/git-exec-and-restage": "^1.0.4", "@types/bluebird": "^3.5.37", "@types/node": "^18.11.8", "@types/nunjucks": "^3.2.2", @@ -77,11 +76,11 @@ "chai": "^4.3.6", "cheerio": "0.22.0", "decache": "^4.6.1", - "eslint": "^8.8.0", + "eslint": "^8.48.0", "eslint-config-hexo": "^5.0.0", "hexo-renderer-marked": "^6.0.0", "husky": "^8.0.1", - "lint-staged": "^13.0.3", + "lint-staged": "^14.0.1", "mocha": "^10.0.0", "sinon": "^15.0.0", "ts-node": "^10.9.1", From 7b588e78aae57e756e4d18bcd78e63d9dc7d34cd Mon Sep 17 00:00:00 2001 From: Uiolee <22849383+uiolee@users.noreply.github.com> Date: Sat, 2 Sep 2023 02:25:37 +0800 Subject: [PATCH 29/29] ci: reduce the running of ci (#5282) --- .github/workflows/linter.yml | 17 +++++++++++++++-- .github/workflows/tester.yml | 25 ++++++++++++++++++++----- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index d3d9678043..8211d38999 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -1,6 +1,19 @@ name: Linter -on: [push, pull_request] +on: + push: + branches: + - "master" + - "v7.0.0" + paths: + - "lib/**" + - "test/**" + - ".github/workflows/linter.yml" + pull_request: + paths: + - "lib/**" + - "test/**" + - ".github/workflows/linter.yml" permissions: contents: read @@ -13,7 +26,7 @@ jobs: - name: Use Node.js 14.x uses: actions/setup-node@v3 with: - node-version: '14.x' + node-version: "14.x" - name: Install Dependencies run: npm install - name: Lint diff --git a/.github/workflows/tester.yml b/.github/workflows/tester.yml index a28cf0a77d..c245376116 100644 --- a/.github/workflows/tester.yml +++ b/.github/workflows/tester.yml @@ -1,6 +1,21 @@ name: Tester -on: [push, pull_request] +on: + push: + branches: + - "master" + - "v7.0.0" + paths: + - "lib/**" + - "test/**" + - "package.json" + - ".github/workflows/tester.yml" + pull_request: + paths: + - "lib/**" + - "test/**" + - "package.json" + - ".github/workflows/tester.yml" permissions: contents: read @@ -11,7 +26,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] - node-version: ['14.x', '16.x', '18.x'] + node-version: ["14.x", "16.x", "18.x"] fail-fast: false steps: - uses: actions/checkout@v3 @@ -27,13 +42,13 @@ jobs: CI: true coverage: permissions: - checks: write # for coverallsapp/github-action to create new checks - contents: read # for actions/checkout to fetch code + checks: write # for coverallsapp/github-action to create new checks + contents: read # for actions/checkout to fetch code runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest] - node-version: ['14.x'] + node-version: ["14.x"] steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node-version }}