Skip to content

Commit

Permalink
refactor: refactor types
Browse files Browse the repository at this point in the history
  • Loading branch information
D-Sketon committed Nov 8, 2023
1 parent 1de27b4 commit be9a1f2
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 43 deletions.
44 changes: 24 additions & 20 deletions lib/hexo/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import loadDatabase from './load_database';
import multiConfigPath from './multi_config_path';
import { deepMerge, full_url_for } from 'hexo-util';
import type Box from '../box';
import type { NodeJSLikeCallback } from '../types';
import type { AssetGenerator, LocalsType, NodeJSLikeCallback, NormalPageGenerator, NormalPostGenerator, PageGenerator, PostGenerator, SiteLocals } from '../types';

let resolveSync; // = require('resolve');

Expand All @@ -50,19 +50,21 @@ const routeCache = new WeakMap();

const castArray = (obj: any) => { return Array.isArray(obj) ? obj : [obj]; };

const mergeCtxThemeConfig = ctx => {
// eslint-disable-next-line no-use-before-define
const mergeCtxThemeConfig = (ctx: Hexo) => {
// Merge hexo.config.theme_config into hexo.theme.config before post rendering & generating
// config.theme_config has "_config.[theme].yml" merged in load_theme_config.js
if (ctx.config.theme_config) {
ctx.theme.config = deepMerge(ctx.theme.config, ctx.config.theme_config);
}
};

const createLoadThemeRoute = function(generatorResult, locals, ctx) {
// eslint-disable-next-line no-use-before-define
const createLoadThemeRoute = function(generatorResult: NormalPageGenerator | NormalPostGenerator, locals: LocalsType, ctx: Hexo) {
const { log, theme } = ctx;
const { path, cache: useCache } = locals;

const layout = [...new Set(castArray(generatorResult.layout))];
const layout: string[] = [...new Set(castArray(generatorResult.layout))];
const layoutLength = layout.length;

// always use cache in fragment_cache
Expand Down Expand Up @@ -96,7 +98,7 @@ const createLoadThemeRoute = function(generatorResult, locals, ctx) {
};
};

function debounce(func: () => void, wait: number) {
function debounce(func: () => void, wait: number): () => void {
let timeout: NodeJS.Timeout;
return function() {
clearTimeout(timeout);
Expand Down Expand Up @@ -342,9 +344,11 @@ class Hexo extends EventEmitter {
});
}

call(name: string, args: any, callback?: NodeJSLikeCallback<any>) {
call(name: string, callback?: NodeJSLikeCallback<any>): Promise<any>;
call(name: string, args: object, callback?: NodeJSLikeCallback<any>): Promise<any>;
call(name: string, args?: object | NodeJSLikeCallback<any>, callback?: NodeJSLikeCallback<any>): Promise<any> {
if (!callback && typeof args === 'function') {
callback = args;
callback = args as NodeJSLikeCallback<any>;
args = {};
}

Expand Down Expand Up @@ -378,7 +382,7 @@ class Hexo extends EventEmitter {

loadPlugin(path: string, callback?: NodeJSLikeCallback<any>): Promise<any> {
return readFile(path).then(script => {
// Based on: https://github.com/joyent/node/blob/v0.10.33/src/node.js#L516
// Based on: https://github.com/nodejs/node-v0.x-archive/blob/v0.10.33/src/node.js#L516
const module = new Module(path);
module.filename = path;
module.paths = Module._nodeModulePaths(path);
Expand Down Expand Up @@ -468,23 +472,21 @@ class Hexo extends EventEmitter {
_generateLocals() {
const { config, env, theme, theme_dir } = this;
const ctx = { config: { url: this.config.url } };
const localsObj = this.locals.toObject();
const localsObj = this.locals.toObject() as SiteLocals;

class Locals {
page: {
path: string;
};
page: NormalPageGenerator | NormalPostGenerator;
path: string;
url: string;
config: object;
theme: object;
layout: string;
env: any;
view_dir: string;
site: object;
site: SiteLocals;
cache?: boolean;

constructor(path: string, locals) {
constructor(path: string, locals: NormalPageGenerator | NormalPostGenerator) {
this.page = { ...locals };
if (this.page.path == null) this.page.path = path;
this.path = path;
Expand All @@ -501,9 +503,9 @@ class Hexo extends EventEmitter {
return Locals;
}

_runGenerators(): Promise<any[]> {
_runGenerators(): Promise<(AssetGenerator | PostGenerator | PageGenerator)[]> {
this.locals.invalidate();
const siteLocals = this.locals.toObject();
const siteLocals = this.locals.toObject() as SiteLocals;
const generators = this.extend.generator.list();
const { log } = this;

Expand All @@ -518,26 +520,28 @@ class Hexo extends EventEmitter {
}, []);
}

_routerRefresh(runningGenerators: Promise<any[]>, useCache: boolean): Promise<void> {
_routerRefresh(runningGenerators: Promise<(AssetGenerator | PostGenerator | PageGenerator)[]>, useCache: boolean): Promise<void> {
const { route } = this;
const routeList = route.list();
const Locals = this._generateLocals();
Locals.prototype.cache = useCache;

return runningGenerators.map(generatorResult => {
return runningGenerators.map((generatorResult: AssetGenerator | PostGenerator | PageGenerator) => {
if (typeof generatorResult !== 'object' || generatorResult.path == null) return undefined;

// add Route
const path = route.format(generatorResult.path);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const { data, layout } = generatorResult;

if (!layout) {
route.set(path, data);
return path;
}

return this.execFilter('template_locals', new Locals(path, data), { context: this })
.then(locals => { route.set(path, createLoadThemeRoute(generatorResult, locals, this)); })
return this.execFilter('template_locals', new Locals(path, data as unknown as NormalPageGenerator | NormalPostGenerator), { context: this })
.then(locals => { route.set(path, createLoadThemeRoute(generatorResult as NormalPageGenerator | NormalPostGenerator, locals, this)); })
.thenReturn(path);
}).then(newRouteList => {
// Remove old routes
Expand Down
14 changes: 2 additions & 12 deletions lib/plugins/filter/template_locals/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
import { Pattern } from 'hexo-util';
import type Hexo from '../../../hexo';
import type { LocalsType } from '../../../types';

interface Locals {
path: string;
page: {
lang: string;
language: string;
canonical_path: string;
};
__: (key: string) => string;
_p: (key: string, options?: any) => string;
}

function i18nLocalsFilter(this: Hexo, locals: Locals): void {
function i18nLocalsFilter(this: Hexo, locals: LocalsType): void {
const { i18n } = this.theme;
const { config } = this;
const i18nDir = config.i18n_dir;
Expand Down
5 changes: 3 additions & 2 deletions lib/plugins/generator/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { extname } from 'path';
import { magenta } from 'picocolors';
import type warehouse from 'warehouse';
import type Hexo from '../../hexo';
import type { AssetGenerator } from '../../types';

interface Data {
modified: boolean;
Expand Down Expand Up @@ -36,7 +37,7 @@ const process = (name: string, ctx: Hexo) => {
data.data = () => ctx.render.render({
path: source,
toString: true
}).catch(err => {
}).catch((err: Error) => {
ctx.log.error({err}, 'Asset render failed: %s', magenta(path));
});
} else {
Expand All @@ -47,7 +48,7 @@ const process = (name: string, ctx: Hexo) => {
});
};

function assetGenerator(this: Hexo): Promise<any[]> {
function assetGenerator(this: Hexo): Promise<AssetGenerator[]> {
return Promise.all([
process('Asset', this),
process('PostAsset', this)
Expand Down
6 changes: 4 additions & 2 deletions lib/plugins/generator/page.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
function pageGenerator(locals) {
return locals.pages.map(page => {
import type { PageGenerator, PageSchema, SiteLocals } from '../../types';

function pageGenerator(locals: SiteLocals): PageGenerator[] {
return locals.pages.map((page: PageSchema) => {
const { path, layout } = page;

if (!layout || layout === 'false' || layout === 'off') {
Expand Down
6 changes: 4 additions & 2 deletions lib/plugins/generator/post.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
function postGenerator(locals) {
import type { PostGenerator, PostSchema, SiteLocals } from '../../types';

function postGenerator(locals: SiteLocals): PostGenerator[] {
const posts = locals.posts.sort('-date').toArray();
const { length } = posts;

return posts.map((post, i) => {
return posts.map((post: PostSchema, i: number) => {
const { path, layout } = post;

if (!layout || layout === 'false') {
Expand Down
4 changes: 2 additions & 2 deletions lib/plugins/helper/date.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import moment from 'moment-timezone';
const { isMoment } = moment;
import moize from 'moize';
import type Hexo from '../../hexo';
import type { LocalsType } from '../../types';

const isDate = (value: moment.MomentInput | moment.Moment): boolean =>
typeof value === 'object' && value instanceof Date && !isNaN(value.getTime());
Expand Down Expand Up @@ -61,7 +61,7 @@ function timeTagHelper(date: string | number | Date | moment.Moment, format: str
return `<time datetime="${toISOString(date)}">${this.date(date, format, getLanguage(this), config.timezone)}</time>`;
}

function getLanguage(ctx) {
function getLanguage(ctx: LocalsType) {
return ctx.page.lang || ctx.page.language || ctx.config.language;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/plugins/helper/is.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function isCurrentHelper(path = '/', strict) {
function isCurrentHelper(path = '/', strict: boolean) {
const currentPath = this.path.replace(/^[^/].*/, '/$&');

if (strict) {
Expand Down
2 changes: 1 addition & 1 deletion lib/plugins/injector/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type Hexo from '../../hexo';

export = (ctx: Hexo) => {
// eslint-disable-next-line no-unused-vars
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { injector } = ctx.extend;
};
3 changes: 2 additions & 1 deletion lib/theme/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class Options {

class View {
public path: string;
public source: any;
public source: string;
public _theme: Theme;
public data: any;
public _compiled: any;
Expand Down Expand Up @@ -89,6 +89,7 @@ class View {
}

_buildLocals(locals: Options) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { layout, _content, ...data } = this.data;
return assignIn({}, locals, data, {
filename: this.source
Expand Down
87 changes: 87 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import moment from 'moment';
import type default_config from './hexo/default_config';

export type NodeJSLikeCallback<R, E = any> = (err: E, result?: R) => void

Expand All @@ -14,6 +15,7 @@ export interface RenderData {
more?: string;
}

// Schema
export interface PostSchema {
id?: string;
_id?: string;
Expand All @@ -39,4 +41,89 @@ export interface PostSchema {
categories?: any;
tags?: any;
__permalink?: string;
__post?: boolean;
canonical_path?: string;
lang?: string;
language?: string;
prev?: PostSchema;
next?: PostSchema;
}

export interface PageSchema {
_id?: string;
title?: string;
date?: moment.Moment,
updated?: moment.Moment,
comments?: boolean;
layout?: string;
_content?: string;
source?: string;
path?: string;
raw?: string;
content?: string;
excerpt?: string;
more?: string;
author?: string;
full_source?: string;
permalink?: string;
tags?: any;
canonical_path?: string;
lang?: string;
language?: string;
__page?: boolean;
}

export interface LocalsType {
page: PostSchema | PageSchema;
path: string;
url: string;
config: typeof default_config;
theme: object;
layout: string;
env: any;
view_dir: string;
site: object;
cache?: boolean;
__?: (key: string) => string;
_p?: (key: string, options?: any) => string;
}

// Generator return types
export interface AssetGenerator {
path: string;
data: {
modified: boolean;
data?: () => any;
}
}

export type SimplePostGenerator = {
path: string;
data: string;
}
export type NormalPostGenerator = {
path: string;
layout: string[];
data: PostSchema;
}
export type PostGenerator = SimplePostGenerator | NormalPostGenerator;


export type SimplePageGenerator = {
path: string;
data: string;
}
export type NormalPageGenerator = {
path: string;
layout: string[];
data: PageSchema;
}
export type PageGenerator = SimplePageGenerator | NormalPageGenerator;

export interface SiteLocals {
posts: any; // _Query
pages: any; // _Query
categories: any; // _Model
tags: any; // _Model
data: object;
}

0 comments on commit be9a1f2

Please sign in to comment.