diff --git a/lib/hexo/index.ts b/lib/hexo/index.ts index 2da92f6b90..c5e48f8723 100644 --- a/lib/hexo/index.ts +++ b/lib/hexo/index.ts @@ -38,6 +38,8 @@ import multiConfigPath from './multi_config_path'; import { deepMerge, full_url_for } from 'hexo-util'; import type Box from '../box'; import type { AssetGenerator, LocalsType, NodeJSLikeCallback, NormalPageGenerator, NormalPostGenerator, PageGenerator, PostGenerator, SiteLocals } from '../types'; +import type { AddSchemaTypeOptions } from 'warehouse/dist/types'; +import type Schema from 'warehouse/dist/schema'; let resolveSync; // = require('resolve'); @@ -440,7 +442,7 @@ class Hexo extends EventEmitter { return Promise.reject(new Error(`Console \`${name}\` has not been registered yet!`)); } - model(name: string, schema?: any) { + model(name: string, schema?: Schema | Record) { return this.database.model(name, schema); } @@ -560,8 +562,8 @@ class Hexo extends EventEmitter { page: NormalPageGenerator | NormalPostGenerator; path: string; url: string; - config: object; - theme: object; + config: any; + theme: any; layout: string; env: any; view_dir: string; diff --git a/lib/plugins/generator/asset.ts b/lib/plugins/generator/asset.ts index 336c4e2612..70fde55d8c 100644 --- a/lib/plugins/generator/asset.ts +++ b/lib/plugins/generator/asset.ts @@ -3,9 +3,9 @@ import { exists, createReadStream } from 'hexo-fs'; import Promise from 'bluebird'; import { extname } from 'path'; import { magenta } from 'picocolors'; -import type warehouse from 'warehouse'; import type Hexo from '../../hexo'; -import type { AssetGenerator } from '../../types'; +import type { AssetGenerator, AssetSchema } from '../../types'; +import type Document from 'warehouse/dist/document'; interface Data { modified: boolean; @@ -13,21 +13,15 @@ interface Data { } const process = (name: string, ctx: Hexo) => { - // @ts-expect-error - return Promise.filter(ctx.model(name).toArray(), (asset: warehouse['Schema']) => exists(asset.source).tap(exist => { - // @ts-expect-error + return Promise.filter(ctx.model(name).toArray(), (asset: Document) => exists(asset.source).tap(exist => { if (!exist) return asset.remove(); - })).map((asset: warehouse['Schema']) => { - // @ts-expect-error + })).map((asset: Document) => { const { source } = asset; - // @ts-expect-error let { path } = asset; 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); diff --git a/lib/plugins/generator/post.ts b/lib/plugins/generator/post.ts index d97030b04f..bf832872ca 100644 --- a/lib/plugins/generator/post.ts +++ b/lib/plugins/generator/post.ts @@ -1,10 +1,11 @@ import type { PostGenerator, PostSchema, SiteLocals } from '../../types'; +import type Document from 'warehouse/dist/document'; function postGenerator(locals: SiteLocals): PostGenerator[] { const posts = locals.posts.sort('-date').toArray(); const { length } = posts; - return posts.map((post: PostSchema, i: number) => { + return posts.map((post: Document, i: number) => { const { path, layout } = post; if (!layout || layout === 'false') { diff --git a/lib/plugins/helper/css.ts b/lib/plugins/helper/css.ts index 9dac2e3588..388f25fa6a 100644 --- a/lib/plugins/helper/css.ts +++ b/lib/plugins/helper/css.ts @@ -1,8 +1,9 @@ import { htmlTag, url_for } from 'hexo-util'; import moize from 'moize'; +import type { LocalsType } from '../../types'; let relative_link = true; -function cssHelper(...args: any[]) { +function cssHelper(this: LocalsType, ...args: any[]) { let result = '\n'; relative_link = this.config.relative_link; diff --git a/lib/plugins/helper/date.ts b/lib/plugins/helper/date.ts index 063a437cb4..4d0451db15 100644 --- a/lib/plugins/helper/date.ts +++ b/lib/plugins/helper/date.ts @@ -29,19 +29,19 @@ function toISOString(date: string | number | Date | moment.Moment) { return new Date(date as (string | number)).toISOString(); } -function dateHelper(date: moment.Moment | moment.MomentInput, format: string) { +function dateHelper(this: LocalsType, date: moment.Moment | moment.MomentInput, format?: string) { const { config } = this; const moment = getMoment(date, getLanguage(this), config.timezone); return moment.format(format || config.date_format); } -function timeHelper(date: moment.Moment | moment.MomentInput, format: string) { +function timeHelper(this: LocalsType, date: moment.Moment | moment.MomentInput, format?: string) { const { config } = this; const moment = getMoment(date, getLanguage(this), config.timezone); return moment.format(format || config.time_format); } -function fullDateHelper(date: moment.Moment | moment.MomentInput, format: string) { +function fullDateHelper(this: LocalsType, date: moment.Moment | moment.MomentInput, format: string) { if (format) { const moment = getMoment(date, getLanguage(this), this.config.timezone); return moment.format(format); @@ -50,15 +50,14 @@ function fullDateHelper(date: moment.Moment | moment.MomentInput, format: string return `${this.date(date)} ${this.time(date)}`; } -function relativeDateHelper(date: moment.Moment | moment.MomentInput) { +function relativeDateHelper(this: LocalsType, date: moment.Moment | moment.MomentInput) { const { config } = this; const moment = getMoment(date, getLanguage(this), config.timezone); return moment.fromNow(); } -function timeTagHelper(date: string | number | Date | moment.Moment, format: string) { - const { config } = this; - return ``; +function timeTagHelper(this: LocalsType, date: string | number | Date | moment.Moment, format: string) { + return ``; } function getLanguage(ctx: LocalsType) { diff --git a/lib/plugins/helper/favicon_tag.ts b/lib/plugins/helper/favicon_tag.ts index 3c00b5dbd5..d65c210306 100644 --- a/lib/plugins/helper/favicon_tag.ts +++ b/lib/plugins/helper/favicon_tag.ts @@ -1,6 +1,7 @@ import { url_for } from 'hexo-util'; +import type { LocalsType } from '../../types'; -function faviconTagHelper(path: string) { +function faviconTagHelper(this: LocalsType, path: string) { return ``; } diff --git a/lib/plugins/helper/feed_tag.ts b/lib/plugins/helper/feed_tag.ts index bb8bca13ab..818c025ea4 100644 --- a/lib/plugins/helper/feed_tag.ts +++ b/lib/plugins/helper/feed_tag.ts @@ -1,5 +1,6 @@ import { url_for } from 'hexo-util'; import moize from 'moize'; +import type { LocalsType } from '../../types'; const feedFn = (str = '') => { if (str) return str.replace(/2$/, ''); @@ -11,7 +12,7 @@ interface Options { type?: string; } -function makeFeedTag(path: string, options: Options = {}, configFeed?: any, configTitle?: string) { +function makeFeedTag(this: LocalsType, path: string, options: Options = {}, configFeed?: any, configTitle?: string) { const title = options.title || configTitle; if (path) { @@ -46,9 +47,9 @@ function makeFeedTag(path: string, options: Options = {}, configFeed?: any, conf return ''; } -function feedTagHelper(path: string, options = {}) { +function feedTagHelper(this: LocalsType, path: string, options: Options = {}) { const { config } = this; - return moize.deep(makeFeedTag.bind(this))(path, options, config.feed, config.title); + return moize.deep(makeFeedTag.bind(this))(path, options, (config as any).feed, config.title); } export = feedTagHelper; diff --git a/lib/plugins/helper/fragment_cache.ts b/lib/plugins/helper/fragment_cache.ts index 91926b919f..a12145770d 100644 --- a/lib/plugins/helper/fragment_cache.ts +++ b/lib/plugins/helper/fragment_cache.ts @@ -7,7 +7,7 @@ export = (ctx: Hexo) => { // reset cache for watch mode ctx.on('generateBefore', () => { cache.flush(); }); - return function fragmentCache(id, fn) { + return function fragmentCache(id: string, fn: () => any) { if (this.cache) return cache.apply(id, fn); const result = fn(); diff --git a/lib/plugins/helper/full_url_for.ts b/lib/plugins/helper/full_url_for.ts index 9484f0e537..8f4071c2fc 100644 --- a/lib/plugins/helper/full_url_for.ts +++ b/lib/plugins/helper/full_url_for.ts @@ -1,6 +1,7 @@ import { full_url_for } from 'hexo-util'; +import type { LocalsType } from '../../types'; -export = function(path: string) { +export = function(this: LocalsType, path: string) { return full_url_for.call(this, path); } diff --git a/lib/plugins/helper/image_tag.ts b/lib/plugins/helper/image_tag.ts index 402c6e3714..6308a883ac 100644 --- a/lib/plugins/helper/image_tag.ts +++ b/lib/plugins/helper/image_tag.ts @@ -1,4 +1,5 @@ import { htmlTag, url_for } from 'hexo-util'; +import type { LocalsType } from '../../types'; interface Options { src?: string; @@ -11,7 +12,7 @@ interface Attrs { [key: string]: string | undefined; } -function imageTagHelper(path: string, options: Options = {}) { +function imageTagHelper(this: LocalsType, path: string, options: Options = {}) { const attrs = Object.assign({ src: url_for.call(this, path) as string }, options); diff --git a/lib/plugins/helper/is.ts b/lib/plugins/helper/is.ts index ef9ec0fc46..3ba7f84232 100644 --- a/lib/plugins/helper/is.ts +++ b/lib/plugins/helper/is.ts @@ -1,4 +1,6 @@ -function isCurrentHelper(path = '/', strict: boolean) { +import type { LocalsType } from '../../types'; + +function isCurrentHelper(this: LocalsType, path = '/', strict: boolean) { const currentPath = this.path.replace(/^[^/].*/, '/$&'); if (strict) { @@ -37,7 +39,7 @@ function isArchiveHelper() { return Boolean(this.page.archive); } -function isYearHelper(year) { +function isYearHelper(year?) { const { page } = this; if (!page.archive) return false; @@ -48,7 +50,7 @@ function isYearHelper(year) { return Boolean(page.year); } -function isMonthHelper(year, month) { +function isMonthHelper(year?, month?) { const { page } = this; if (!page.archive) return false; @@ -63,7 +65,7 @@ function isMonthHelper(year, month) { return Boolean(page.year && page.month); } -function isCategoryHelper(category) { +function isCategoryHelper(category?) { if (category) { return this.page.category === category; } @@ -71,7 +73,7 @@ function isCategoryHelper(category) { return Boolean(this.page.category); } -function isTagHelper(tag) { +function isTagHelper(tag?) { if (tag) { return this.page.tag === tag; } diff --git a/lib/plugins/helper/js.ts b/lib/plugins/helper/js.ts index 8ca44e5c52..c5709e3f52 100644 --- a/lib/plugins/helper/js.ts +++ b/lib/plugins/helper/js.ts @@ -1,8 +1,9 @@ import { htmlTag, url_for } from 'hexo-util'; import moize from 'moize'; +import type { LocalsType } from '../../types'; let relative_link = true; -function jsHelper(...args: any[]) { +function jsHelper(this: LocalsType, ...args: any[]) { let result = '\n'; relative_link = this.config.relative_link; diff --git a/lib/plugins/helper/link_to.ts b/lib/plugins/helper/link_to.ts index cb0792d172..ce62a61da8 100644 --- a/lib/plugins/helper/link_to.ts +++ b/lib/plugins/helper/link_to.ts @@ -1,4 +1,5 @@ import { htmlTag, url_for } from 'hexo-util'; +import type { LocalsType } from '../../types'; interface Options { href?: string; @@ -19,7 +20,7 @@ interface Attrs { [key: string]: string | boolean | null | undefined; } -function linkToHelper(path: string, text: string, options: Options | boolean = {}) { +function linkToHelper(this: LocalsType, path: string, text: string, options: Options | boolean = {}) { if (typeof options === 'boolean') options = {external: options}; if (!text) text = path.replace(/^https?:\/\/|\/$/g, ''); diff --git a/lib/plugins/helper/list_archives.ts b/lib/plugins/helper/list_archives.ts index 2572a25cb7..60824abd33 100644 --- a/lib/plugins/helper/list_archives.ts +++ b/lib/plugins/helper/list_archives.ts @@ -1,3 +1,4 @@ +import type { LocalsType } from '../../types'; import { toMomentLocale } from './date'; import { url_for } from 'hexo-util'; @@ -19,7 +20,7 @@ interface Data { count: number; } -function listArchivesHelper(options: Options = {}) { +function listArchivesHelper(this: LocalsType, options: Options = {}) { const { config } = this; const archiveDir = config.archive_dir; const { timezone } = config; diff --git a/lib/plugins/helper/list_categories.ts b/lib/plugins/helper/list_categories.ts index b2c1fd4e58..26f55e25e2 100644 --- a/lib/plugins/helper/list_categories.ts +++ b/lib/plugins/helper/list_categories.ts @@ -1,10 +1,29 @@ import { url_for } from 'hexo-util'; +import type { CategorySchema, LocalsType } from '../../types'; +import type Query from 'warehouse/dist/query'; + +interface Options { + style?: string; + class?: string; + depth?: number | string; + orderby?: string; + order?: number; + show_count?: boolean; + show_current?: boolean; + transform?: (name: string) => string; + separator?: string; + suffix?: string; + children_indicator?: boolean; +} -function listCategoriesHelper(categories, options) { +function listCategoriesHelper(this: LocalsType, options?: Options): string; +function listCategoriesHelper(this: LocalsType, categories: Query, options?: Options): string; +function listCategoriesHelper(this: LocalsType, categories?: Query | Options, options?: Options) { if (!options && (!categories || !Object.prototype.hasOwnProperty.call(categories, 'length'))) { - options = categories; + options = categories as Options; categories = this.site.categories; } + categories = categories as Query; if (!categories || !categories.length) return ''; options = options || {}; @@ -12,7 +31,7 @@ function listCategoriesHelper(categories, options) { const { style = 'list', transform, separator = ', ', suffix = '' } = options; const showCount = Object.prototype.hasOwnProperty.call(options, 'show_count') ? options.show_count : true; const className = options.class || 'category'; - const depth = options.depth ? parseInt(options.depth, 10) : 0; + const depth = options.depth ? parseInt(String(options.depth), 10) : 0; const orderby = options.orderby || 'name'; const order = options.order || 1; const showCurrent = options.show_current || false; @@ -27,13 +46,13 @@ function listCategoriesHelper(categories, options) { query.parent = {$exists: false}; } - return categories.find(query).sort(orderby, order); + return (categories as Query).find(query).sort(orderby, order); }; const hierarchicalList = (level: number, parent?: any) => { let result = ''; - prepareQuery(parent).forEach(cat => { + prepareQuery(parent).forEach((cat: CategorySchema) => { let child; if (!depth || level + 1 < depth) { child = hierarchicalList(level + 1, cat._id); diff --git a/lib/plugins/helper/list_posts.ts b/lib/plugins/helper/list_posts.ts index a3d9b9b5ca..10a6223e6b 100644 --- a/lib/plugins/helper/list_posts.ts +++ b/lib/plugins/helper/list_posts.ts @@ -1,11 +1,27 @@ import { url_for } from 'hexo-util'; +import type { LocalsType, PostSchema } from '../../types'; +import type Query from 'warehouse/dist/query'; + +interface Options { + style?: string; + class?: string; + amount?: number; + orderby?: string; + order?: number; + transform?: (name: string) => string; + separator?: string; +} -function listPostsHelper(posts, options) { +function listPostsHelper(this: LocalsType, options?: Options): string; +function listPostsHelper(this: LocalsType, posts: Query, options?: Options): string; +function listPostsHelper(this: LocalsType, posts?: Query | Options, options?: Options) { if (!options && (!posts || !Object.prototype.hasOwnProperty.call(posts, 'length'))) { - options = posts; + options = posts as Options; posts = this.site.posts; } + posts = posts as Query; + options = options || {}; const { style = 'list', transform, separator = ', ' } = options; diff --git a/lib/plugins/helper/list_tags.ts b/lib/plugins/helper/list_tags.ts index b7b0d0b523..e09fc0a321 100644 --- a/lib/plugins/helper/list_tags.ts +++ b/lib/plugins/helper/list_tags.ts @@ -1,11 +1,28 @@ import { url_for, escapeHTML } from 'hexo-util'; import moize from 'moize'; +import type { LocalsType, TagSchema } from '../../types'; +import type Query from 'warehouse/dist/query'; + +interface Options { + style?: string; + class?: any; + amount?: number; + orderby?: string; + order?: number; + transform?: (name: string) => string; + separator?: string; + show_count?: boolean; + suffix?: string; +} -function listTagsHelper(tags, options?) { +function listTagsHelper(this: LocalsType, options?: Options): string; +function listTagsHelper(this: LocalsType, tags: Query, options?: Options): string; +function listTagsHelper(this: LocalsType, tags?: Query | Options, options?: Options) { if (!options && (!tags || !Object.prototype.hasOwnProperty.call(tags, 'length'))) { - options = tags; + options = tags as Options; tags = this.site.tags; } + tags = tags as Query; if (!tags || !tags.length) return ''; options = options || {}; @@ -87,13 +104,15 @@ function listTagsHelper(tags, options?) { return result; } - -function listTagsHelperFactory(tags, options) { +function listTagsHelperFactory(options?: Options): string; +function listTagsHelperFactory(tags: Query, options?: Options): string; +function listTagsHelperFactory(tags?: Query | Options, options?: Options) { const transformArgs = () => { if (!options && (!tags || !Object.prototype.hasOwnProperty.call(tags, 'length'))) { - options = tags; + options = tags as Options; tags = this.site.tags; } + tags = tags as Query; return [tags.toArray(), options]; }; diff --git a/lib/plugins/helper/markdown.ts b/lib/plugins/helper/markdown.ts index 9465bbb671..bda3907f50 100644 --- a/lib/plugins/helper/markdown.ts +++ b/lib/plugins/helper/markdown.ts @@ -1,4 +1,6 @@ -function markdownHelper(text: string, options) { +import type { LocalsType } from '../../types'; + +function markdownHelper(this: LocalsType, text: string, options: any) { return this.render(text, 'markdown', options); } diff --git a/lib/plugins/helper/meta_generator.ts b/lib/plugins/helper/meta_generator.ts index 4b0036c558..1d4abb0863 100644 --- a/lib/plugins/helper/meta_generator.ts +++ b/lib/plugins/helper/meta_generator.ts @@ -1,4 +1,6 @@ -function metaGeneratorHelper() { +import type { LocalsType } from '../../types'; + +function metaGeneratorHelper(this: LocalsType) { return ``; } diff --git a/lib/plugins/helper/open_graph.ts b/lib/plugins/helper/open_graph.ts index 27d142f8bc..bcba5062cf 100644 --- a/lib/plugins/helper/open_graph.ts +++ b/lib/plugins/helper/open_graph.ts @@ -1,6 +1,7 @@ -import { isMoment, isDate } from 'moment'; +import { isMoment, isDate, Moment } from 'moment'; import { encodeURL, prettyUrls, stripHTML, escapeHTML } from 'hexo-util'; import moize from 'moize'; +import type { LocalsType } from '../../types'; const localeMap = { 'en': 'en_US', @@ -61,8 +62,8 @@ interface Options { url?: string; site_name?: string; twitter_card?: string; - date?: boolean; - updated?: boolean; + date?: Moment | Date | false; + updated?: Moment | Date | false; language?: string; author?: string; twitter_image?: string; @@ -72,12 +73,12 @@ interface Options { fb_app_id?: string; } -function openGraphHelper(options: Options = {}) { +function openGraphHelper(this: LocalsType, options: Options = {}) { const { config, page } = this; const { content } = page; let images = options.image || options.images || page.photos || []; let description = options.description || page.description || page.excerpt || content || config.description; - let keywords = (page.tags && page.tags.length ? page.tags : undefined) || config.keywords || false; + let keywords = (page.tags && page.tags.length ? page.tags : undefined) || (config as any).keywords || false; const title = options.title || page.title || config.title; const type = options.type || (this.is_post() ? 'article' : 'website'); const url = prettyUrls(options.url || this.url, config.pretty_urls); diff --git a/lib/plugins/helper/paginator.ts b/lib/plugins/helper/paginator.ts index 429aff8b4d..caeba1353d 100644 --- a/lib/plugins/helper/paginator.ts +++ b/lib/plugins/helper/paginator.ts @@ -1,5 +1,5 @@ import { htmlTag, url_for } from 'hexo-util'; -import type Hexo from '../../hexo'; +import type { LocalsType } from '../../types'; interface Options { base?: string; @@ -23,13 +23,13 @@ interface Options { transform?: (i: number) => any; } -const createLink = (options: Options, ctx: Hexo) => { +const createLink = (options: Options, ctx: LocalsType) => { const { base, format } = options; return (i: number) => url_for.call(ctx, i === 1 ? base : base + format.replace('%d', String(i))); }; -const createPageTag = (options: Options, ctx: Hexo) => { +const createPageTag = (options: Options, ctx: LocalsType) => { const link = createLink(options, ctx); const { current, @@ -47,7 +47,7 @@ const createPageTag = (options: Options, ctx: Hexo) => { }; }; -const showAll = (tags: string[], options: Options, ctx: Hexo) => { +const showAll = (tags: string[], options: Options, ctx: LocalsType) => { const { total } = options; const pageLink = createPageTag(options, ctx); @@ -57,7 +57,7 @@ const showAll = (tags: string[], options: Options, ctx: Hexo) => { } }; -const paginationPartShow = (tags, options, ctx: Hexo) => { +const paginationPartShow = (tags, options, ctx: LocalsType) => { const { current, total, @@ -109,7 +109,7 @@ const paginationPartShow = (tags, options, ctx: Hexo) => { } }; -function paginatorHelper(options: Options = {}) { +function paginatorHelper(this: LocalsType, options: Options = {}) { options = Object.assign({ base: this.page.base || '', current: this.page.current || 0, diff --git a/lib/plugins/helper/partial.ts b/lib/plugins/helper/partial.ts index fac560117d..a0e2eda212 100644 --- a/lib/plugins/helper/partial.ts +++ b/lib/plugins/helper/partial.ts @@ -1,12 +1,13 @@ import { dirname, join } from 'path'; import type Hexo from '../../hexo'; +import type { LocalsType } from '../../types'; interface Options { cache?: boolean | string; only?: boolean; } -export = (ctx: Hexo) => function partial(name: string, locals: any, options: Options = {}) { +export = (ctx: Hexo) => function partial(this: LocalsType, name: string, locals: any, options: Options = {}) { if (typeof name !== 'string') throw new TypeError('name must be a string!'); const { cache } = options; diff --git a/lib/plugins/helper/search_form.ts b/lib/plugins/helper/search_form.ts index 6414615e82..4eb414245b 100644 --- a/lib/plugins/helper/search_form.ts +++ b/lib/plugins/helper/search_form.ts @@ -1,4 +1,5 @@ import moize from 'moize'; +import type { LocalsType } from '../../types'; interface Options { class?: string; @@ -6,7 +7,7 @@ interface Options { button?: string | boolean; } -function searchFormHelper(options: Options = {}) { +function searchFormHelper(this: LocalsType, options: Options = {}) { const { config } = this; const className = options.class || 'search-form'; const { text = 'Search', button } = options; diff --git a/lib/plugins/helper/tagcloud.ts b/lib/plugins/helper/tagcloud.ts index 0b9a58d0b0..aeff9a4e87 100644 --- a/lib/plugins/helper/tagcloud.ts +++ b/lib/plugins/helper/tagcloud.ts @@ -1,11 +1,34 @@ import { Color, url_for } from 'hexo-util'; import moize from 'moize'; +import type { LocalsType, TagSchema } from '../../types'; +import type Query from 'warehouse/dist/query'; + +interface Options { + min_font?: number; + max_font?: number; + orderby?: string; + order?: number; + unit?: string; + color?: boolean; + class?: string; + show_count?: boolean; + count_class?: string; + level?: number; + transform?: (name: string) => string; + separator?: string; + amount?: number; + start_color?: string; + end_color?: string; +} -function tagcloudHelper(tags, options?) { +function tagcloudHelper(this: LocalsType, options?: Options); +function tagcloudHelper(this: LocalsType, tags: Query, options?: Options); +function tagcloudHelper(this: LocalsType, tags?: Query | Options, options?: Options) { if (!options && (!tags || !Object.prototype.hasOwnProperty.call(tags, 'length'))) { - options = tags; + options = tags as Options; tags = this.site.tags; } + tags = tags as Query; if (!tags || !tags.length) return ''; options = options || {}; @@ -75,12 +98,15 @@ function tagcloudHelper(tags, options?) { return result.join(separator); } -function tagcloudHelperFactory(tags, options) { +function tagcloudHelperFactory(this: LocalsType, options?: Options); +function tagcloudHelperFactory(this: LocalsType, tags: Query, options?: Options); +function tagcloudHelperFactory(this: LocalsType, tags?: Query | Options, options?: Options) { const transformArgs = () => { if (!options && (!tags || !Object.prototype.hasOwnProperty.call(tags, 'length'))) { - options = tags; + options = tags as Options; tags = this.site.tags; } + tags = tags as Query; return [tags.toArray(), options]; }; diff --git a/lib/plugins/helper/url_for.ts b/lib/plugins/helper/url_for.ts index e7c58dd05d..3ee9547344 100644 --- a/lib/plugins/helper/url_for.ts +++ b/lib/plugins/helper/url_for.ts @@ -1,9 +1,10 @@ import { url_for } from 'hexo-util'; +import type { LocalsType } from '../../types'; interface Options { relative?: boolean } -export = function(path: string, options: Options = {}) { +export = function(this: LocalsType, path: string, options: Options = {}) { return url_for.call(this, path, options); } diff --git a/lib/theme/index.ts b/lib/theme/index.ts index 41c83d6bfe..d28940cbcc 100644 --- a/lib/theme/index.ts +++ b/lib/theme/index.ts @@ -10,7 +10,7 @@ import type Hexo from '../hexo'; import type { Pattern } from 'hexo-util'; class Theme extends Box { - public config: object; + public config: any; public views: Record>; public i18n: I18n; public View: typeof View; @@ -19,7 +19,7 @@ class Theme extends Box { process: (...args: any[]) => any; }[]; - constructor(ctx: Hexo, options?: object) { + constructor(ctx: Hexo, options?: any) { super(ctx, ctx.theme_dir, options); this.config = {}; diff --git a/lib/types.ts b/lib/types.ts index 6959a456cc..a22c081182 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -1,5 +1,36 @@ import moment from 'moment'; import type default_config from './hexo/default_config'; +import type Query from 'warehouse/dist/query'; +import type css from './plugins/helper/css'; +import type { date, date_xml, time, full_date, relative_date, time_tag, moment as _moment } from './plugins/helper/date'; +import type { inspectObject, log } from './plugins/helper/debug'; +import type favicon_tag from './plugins/helper/favicon_tag'; +import type feed_tag from './plugins/helper/feed_tag'; +import type { titlecase, word_wrap, truncate, stripHTML, escapeHTML } from './plugins/helper/format'; +import type fragment_cache from './plugins/helper/fragment_cache'; +import type full_url_for from './plugins/helper/full_url_for'; +import type gravatar from './plugins/helper/gravatar'; +import type image_tag from './plugins/helper/image_tag'; +import type { current, home, home_first_page, post, page, archive, year, month, category, tag } from './plugins/helper/is'; +import type js from './plugins/helper/js'; +import type link_to from './plugins/helper/link_to'; +import type list_archives from './plugins/helper/list_archives'; +import type list_categories from './plugins/helper/list_categories'; +import type list_posts from './plugins/helper/list_posts'; +import type list_tags from './plugins/helper/list_tags'; +import type mail_to from './plugins/helper/mail_to'; +import type markdown from './plugins/helper/markdown'; +import type meta_generator from './plugins/helper/meta_generator'; +import type number_format from './plugins/helper/number_format'; +import type open_graph from './plugins/helper/open_graph'; +import type paginator from './plugins/helper/paginator'; +import type relative_url from './plugins/helper/relative_url'; +import type render from './plugins/helper/render'; +import type search_form from './plugins/helper/search_form'; +import type tag_cloud from './plugins/helper/tagcloud'; +import type toc from './plugins/helper/toc'; +import type url_for from './plugins/helper/url_for'; +import Model from 'warehouse/dist/model'; export type NodeJSLikeCallback = (err: E, result?: R) => void @@ -7,7 +38,7 @@ export interface RenderData { engine?: string; content?: string; disableNunjucks?: boolean; - markdown?: object; + markdown?: any; source?: string; titlecase?: boolean; title?: string; @@ -17,8 +48,8 @@ export interface RenderData { // Schema export interface PostSchema { - id?: string; - _id?: string; + id?: string | number; + _id?: string | number; title?: string; date?: moment.Moment, updated?: moment.Moment, @@ -47,10 +78,15 @@ export interface PostSchema { language?: string; prev?: PostSchema; next?: PostSchema; + base?: string; + current?: number; + total?: number; + description?: string; + } export interface PageSchema { - _id?: string; + _id?: string | number; title?: string; date?: moment.Moment, updated?: moment.Moment, @@ -71,6 +107,37 @@ export interface PageSchema { lang?: string; language?: string; __page?: boolean; + base?: string; + current?: number; + total?: number; + photos?: string[]; + description?: string; +} + +export interface CategorySchema { + id?: string | number; + _id?: string | number; + name?: string; + parent?: string | number; + slug?: string; + path?: string; + permalink?: string; + posts?: any; + length?: number; +} + +export interface TagSchema { + id?: string | number; + _id?: string | number; + name?: string; +} + +export interface AssetSchema { + _id?: string; + path: string; + modified: boolean; + renderable: boolean; + source: string; } export interface LocalsType { @@ -78,12 +145,66 @@ export interface LocalsType { path: string; url: string; config: typeof default_config; - theme: object; - layout: string; + theme: any; + layout: string | boolean; env: any; view_dir: string; - site: object; + site: any; cache?: boolean; + body?: string; + filename?: string; + css: typeof css; + date: typeof date; + date_xml: typeof date_xml; + escape_html: typeof escapeHTML; + favicon_tag: typeof favicon_tag; + feed_tag: typeof feed_tag; + fragment_cache: ReturnType; + full_date: typeof full_date; + full_url_for: typeof full_url_for; + gravatar: typeof gravatar; + image_tag: typeof image_tag; + inspect: typeof inspectObject; + is_archive: typeof archive; + is_category: typeof category; + is_current: typeof current; + is_home: typeof home; + is_home_first_page: typeof home_first_page; + is_month: typeof month; + is_page: typeof page; + is_post: typeof post; + is_tag: typeof tag; + is_year: typeof year; + js: typeof js; + link_to: typeof link_to; + list_archives: typeof list_archives; + list_categories: typeof list_categories; + list_posts: typeof list_posts; + list_tags: typeof list_tags; + log: typeof log; + mail_to: typeof mail_to; + markdown: typeof markdown; + meta_generator: typeof meta_generator; + moment: typeof _moment; + number_format: typeof number_format; + open_graph: typeof open_graph; + paginator: typeof paginator; + partial: ReturnType; + relative_date: typeof relative_date; + relative_url: typeof relative_url; + render: ReturnType; + search_form: typeof search_form; + strip_html: typeof stripHTML; + tag_cloud: typeof tag_cloud; + tagcloud: typeof tag_cloud; + time: typeof time; + time_tag: typeof time_tag; + titlecase: typeof titlecase; + toc: typeof toc; + trim: typeof stripHTML; + truncate: typeof truncate; + url_for: typeof url_for; + word_wrap: typeof word_wrap; __?: (key: string) => string; _p?: (key: string, options?: any) => string; } @@ -121,9 +242,9 @@ export type NormalPageGenerator = { export type PageGenerator = SimplePageGenerator | NormalPageGenerator; export interface SiteLocals { - posts: any; // _Query - pages: any; // _Query - categories: any; // _Model - tags: any; // _Model - data: object; + posts: Query; // _Query + pages: Query; // _Query + categories: Model; // _Model + tags: Model; // _Model + data: any; } diff --git a/package.json b/package.json index 6322eb4d52..509fd6a11e 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "text-table": "^0.2.0", "tildify": "^2.0.0", "titlecase": "^1.1.3", - "warehouse": "^5.0.0" + "warehouse": "^5.0.1" }, "devDependencies": { "@types/abbrev": "^1.1.3",