From 725422ae052591b20c71bc8288ab29849c74dc4c Mon Sep 17 00:00:00 2001 From: Pcrab Date: Thu, 20 Apr 2023 21:56:05 +0800 Subject: [PATCH] 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",