Skip to content

Commit cb07377

Browse files
committed
feat(types): definePluginEntry helper to infer type for plugin entry
1 parent 2f707a6 commit cb07377

File tree

13 files changed

+477
-30
lines changed

13 files changed

+477
-30
lines changed

packages/@vuepress/core/lib/node/Page.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ module.exports = class Page {
209209
}
210210

211211
/**
212-
* get date of a page.
212+
* date of current page.
213213
*
214214
* @returns {null|string}
215215
* @api public

packages/@vuepress/types/index.d.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import {
22
UserConfig,
33
ThemeConfig,
4+
PluginOptions,
45
DefaultThemeConfig,
5-
ThemeEntry
6+
UserThemeEntry,
7+
UserPluginEntry,
68
} from './lib'
79

810
export * from './lib'
@@ -28,4 +30,11 @@ export function defineConfig4CustomTheme<T extends ThemeConfig = ThemeConfig>(
2830
*
2931
* @see https://vuepress.vuejs.org/theme/option-api.html
3032
*/
31-
export function defineThemeEntry(config: ThemeEntry): void;
33+
export function defineThemeEntry<T extends ThemeConfig = ThemeConfig>(config: UserThemeEntry<T>): void;
34+
35+
/**
36+
* A helper function to define VuePress theme entry file.
37+
*
38+
* @see https://vuepress.vuejs.org/plugin/writing-a-plugin.html
39+
*/
40+
export function definePluginEntry<T extends PluginOptions = PluginOptions>(config: UserPluginEntry<T>): void;

packages/@vuepress/types/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ function define(config) {
44
exports.defineConfig = define;
55
exports.defineConfig4CustomTheme = define;
66
exports.defineThemeEntry = define;
7+
exports.definePluginEntry = define;

packages/@vuepress/types/lib/config.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import ChainWebpackConfig from "webpack-chain";
21
import { PostCssLoaderOptions } from "./style";
32
import { MarkdownConfig } from "./markdown";
43
import { LocaleConfig } from "./locale";
54
import { ThemeConfig } from "./theme";
6-
import { Plugins } from "./plugin";
5+
import { UserPlugins } from "./plugin";
76
import { Context } from "./context";
7+
import { ChainWebpack } from "./shared";
88

99
/**
1010
* HTML tag name
@@ -124,7 +124,7 @@ export interface Config<T extends ThemeConfig> {
124124
*
125125
* @see https://vuepress.vuejs.org/config/#plugins
126126
*/
127-
plugins?: Plugins;
127+
plugins?: UserPlugins;
128128
/**
129129
* Markdown options.
130130
*
@@ -180,7 +180,7 @@ export interface Config<T extends ThemeConfig> {
180180
*
181181
* @see https://vuepress.vuejs.org/config/#chainwebpack
182182
*/
183-
chainWebpack?: (config: ChainWebpackConfig, isServer: boolean) => void;
183+
chainWebpack?: ChainWebpack;
184184
/**
185185
* Set to true if you are only targeting evergreen browsers.
186186
*

packages/@vuepress/types/lib/context.ts

+78-8
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,94 @@
11
import { ThemeConfig } from "./theme";
22
import { Config } from "./config";
3+
import { Lang } from "./lang";
4+
import { isString } from "../../shared-utils/src/datatypes";
35

46
/**
57
* Page instance.
68
*
79
* @todo distinguish public api and private api.
810
* @see https://github.com/vuejs/vuepress/blob/master/packages/%40vuepress/core/lib/node/Page.js
911
*/
10-
export interface Page {
12+
export interface Page<
13+
T extends ThemeConfig = ThemeConfig,
14+
C extends Config<T> = Config<ThemeConfig>
15+
> {
16+
/**
17+
* file's absolute path
18+
*/
19+
_filePath;
20+
/**
21+
* Access the client global computed mixins at build time, e.g _computed.$localePath.
22+
*/
23+
_computed: Readonly<{
24+
$site: C;
25+
$themeConfig: T;
26+
$frontmatter: Record<string, unknown>;
27+
$localeConfig: Record<string, unknown>;
28+
$siteTitle: string;
29+
$canonicalUrl: string;
30+
$title: string;
31+
$description: string;
32+
$lang: Lang;
33+
$localePath: string;
34+
$themeLocaleConfig: Record<string, unknown>;
35+
$page: Page;
36+
}>;
37+
/**
38+
* Page file's raw content string
39+
*/
40+
_content: string;
41+
/**
42+
* Page file's content string without frontmatter
43+
*/
44+
_strippedContent: string;
45+
/**
46+
* Page's unique hash key
47+
*/
48+
key: string;
49+
/**
50+
* Page's frontmatter object
51+
*/
52+
frontmatter: Record<string, unknown>;
53+
/**
54+
* Current page's default link (follow the file hierarchy)
55+
*/
56+
regularPath: string;
57+
/**
58+
* Current page's real link (use regularPath when permalink does not exist)
59+
*/
1160
path: string;
61+
/**
62+
* Page's title
63+
*/
1264
title: string;
13-
content: string;
14-
filePath: string;
15-
relative: string;
65+
/**
66+
* Page's relative path
67+
*/
68+
relativePath: string;
69+
/**
70+
* Page's permalink
71+
*/
1672
permalink: string;
17-
frontmatter: string;
73+
/**
74+
* Name of page's parent directory.
75+
*/
1876
dirname: string;
77+
/**
78+
* file name of page's source markdown file, or the last cut of regularPath.
79+
*/
1980
filename: string;
81+
/**
82+
* slugified file name.
83+
*/
2084
slug: string;
85+
/**
86+
* stripped file name.
87+
*/
2188
strippedFilename: string;
89+
/**
90+
* date of current page.
91+
*/
2292
date: string;
2393
}
2494

@@ -28,8 +98,8 @@ export interface Page {
2898
* @see https://vuepress.vuejs.org/plugin/context-api.html
2999
*/
30100
export interface Context<
31-
T extends ThemeConfig = ThemeConfig,
32-
C extends Config<T> = Config<ThemeConfig>
101+
T extends ThemeConfig = ThemeConfig,
102+
C extends Config<T> = Config<ThemeConfig>
33103
> {
34104
/**
35105
* Whether VuePress run in production environment mode.
@@ -38,7 +108,7 @@ C extends Config<T> = Config<ThemeConfig>
38108
/**
39109
* A list of Page objects
40110
*/
41-
pages: Page[];
111+
pages: Array<Page<T, C>>;
42112
/**
43113
* Root directory where the documents are located.
44114
*/

packages/@vuepress/types/lib/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ export * from './style'
55
export * from './context'
66
export * from './theme-default'
77
export * from './theme'
8+
export * from './plugin'
9+
export * from './plugin-api'

packages/@vuepress/types/lib/markdown.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import MarkdownIt from "markdown-it";
2+
import { Hook } from "./shared";
3+
4+
export type ExtendMarkdown = Hook<[MarkdownIt], unknown>;
5+
16
/**
27
* Markdown config.
38
*/
@@ -74,7 +79,7 @@ export interface MarkdownConfig {
7479
*
7580
* @see https://vuepress.vuejs.org/config/#markdown-extendmarkdown
7681
*/
77-
extendMarkdown?: Function;
82+
extendMarkdown?: ExtendMarkdown;
7883
/**
7984
* @see https://vuepress.vuejs.org/config/#markdown-extractheaders
8085
*/
+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import { Application } from "express";
2+
import WebpackDevServer from "webpack-dev-server";
3+
import { UserPlugins, PluginOptions } from "./plugin";
4+
import { ChainWebpack, Hook, AsyncHook } from "./shared";
5+
import { Page, Context } from "./context";
6+
import { ExtendMarkdown } from "./markdown";
7+
8+
export type PlainObjectWithStringValue = Record<string, string>;
9+
10+
/**
11+
* Plugin Life Cycle
12+
*/
13+
export type LifeCycleHook$Ready = AsyncHook<[], unknown>;
14+
export type LifeCycleHook$Updated = Hook<[], unknown>;
15+
export type LifeCycleHook$Generated = Hook<[], unknown>;
16+
17+
/**
18+
* Plugin Options API
19+
*/
20+
export type PluginEntryOptions = {
21+
/**
22+
* Current name
23+
*/
24+
name: string;
25+
/**
26+
* Sub plugins
27+
*/
28+
plugins: UserPlugins;
29+
/**
30+
* Edit the internal webpack config with webpack-chain.
31+
*
32+
* @see https://vuepress.vuejs.org/plugin/option-api.html#chainwebpack
33+
*/
34+
chainWebpack?: ChainWebpack;
35+
/**
36+
* Specify define
37+
*
38+
* @see https://vuepress.vuejs.org/plugin/option-api.html#define
39+
*/
40+
define?: PlainObjectWithStringValue | Hook<[], PlainObjectWithStringValue>;
41+
/**
42+
* Specify alias
43+
*
44+
* @see https://vuepress.vuejs.org/plugin/option-api.html#alias
45+
*/
46+
alias?: PlainObjectWithStringValue;
47+
/**
48+
* Equivalent to `before` in `webpack-dev-server`
49+
*
50+
* @see https://vuepress.vuejs.org/plugin/option-api.html#beforedevserver
51+
*/
52+
beforeDevServer?: Hook<[Application, WebpackDevServer], unknown>;
53+
/**
54+
* Equivalent to `after` in `webpack-dev-server`
55+
*
56+
* @see https://vuepress.vuejs.org/plugin/option-api.html#afterdevserver
57+
*/
58+
afterDevServer?: Hook<[Application, WebpackDevServer], unknown>;
59+
/**
60+
* A function to edit default config or apply extra plugins to the `markdown-it` instance.
61+
*
62+
* @see https://vuepress.vuejs.org/plugin/option-api.html#extendmarkdown
63+
*/
64+
extendMarkdown?: ExtendMarkdown;
65+
/**
66+
* Edit the internal Markdown config with `markdown-it-chain`
67+
*
68+
* @see https://vuepress.vuejs.org/plugin/option-api.html#chainmarkdown
69+
*/
70+
chainMarkdown?: Hook<[], unknown>;
71+
/**
72+
* This option accepts absolute file path(s) pointing to the enhancement file(s).
73+
*
74+
* @see https://vuepress.vuejs.org/plugin/option-api.html#enhanceappfiles
75+
*/
76+
enhanceAppFiles?:
77+
| string
78+
| string[]
79+
| AsyncHook<[], { name: string; content: string }>;
80+
/**
81+
* Generate some client modules at compile time.
82+
*
83+
* @see https://vuepress.vuejs.org/plugin/option-api.html#clientdynamicmodules
84+
*/
85+
clientDynamicModules?: AsyncHook<[], { name: string; content: string }>;
86+
/**
87+
* A function used to extend or edit the $page object
88+
*
89+
* @see https://vuepress.vuejs.org/plugin/option-api.html#extendpagedata
90+
*/
91+
extendPageData: Hook<[Page], unknown>;
92+
/**
93+
* A path to the mixin file which allows you to control the lifecycle of root component.
94+
*
95+
* @see https://vuepress.vuejs.org/plugin/option-api.html#clientrootmixin
96+
*/
97+
clientRootMixin: string;
98+
/**
99+
* Add extra pages pointing to a Markdown file:
100+
*
101+
* @see https://vuepress.vuejs.org/plugin/option-api.html#additionalpages
102+
*/
103+
additionalPages:
104+
| Array<{ path: string; filePath: string }>
105+
| AsyncHook<
106+
[],
107+
Array<{
108+
path: string;
109+
content: string;
110+
frontmatter: Record<string, any>;
111+
}>
112+
>;
113+
/**
114+
* Define global ui components fixed somewhere on the page.
115+
*
116+
* @see https://vuepress.vuejs.org/plugin/option-api.html#globaluicomponents
117+
*/
118+
globalUIComponents?: string | string[];
119+
/**
120+
* Register a extra command to enhance the CLI of VuePress.
121+
*
122+
* @see https://vuepress.vuejs.org/plugin/option-api.html#extendcli
123+
*/
124+
extendCli?: Function;
125+
};
126+
127+
/**
128+
* Export type of plugin entry
129+
*
130+
* @see https://vuepress.vuejs.org/plugin/writing-a-plugin.html
131+
*/
132+
export type PluginEntry = PluginEntryOptions & {
133+
/**
134+
* The ready hook is executed after the application is initialized.
135+
*
136+
* @see https://vuepress.vuejs.org/plugin/life-cycle.html#ready
137+
*/
138+
ready: AsyncHook<[], unknown>;
139+
/**
140+
* Trigger when a new compilation is triggered
141+
*
142+
* @see https://vuepress.vuejs.org/plugin/life-cycle.html#updated
143+
*/
144+
updated: Hook<[], unknown>;
145+
/**
146+
* Called when a (production) build finishes, with an array of generated page HTML paths.
147+
*
148+
* @see https://vuepress.vuejs.org/plugin/life-cycle.html#generated
149+
*/
150+
generated: AsyncHook<[string[]], unknown>;
151+
};
152+
153+
/**
154+
* Export type of plugin entry with function support
155+
*
156+
* @see https://vuepress.vuejs.org/plugin/writing-a-plugin.html
157+
*/
158+
export type UserPluginEntry<T extends PluginOptions = PluginOptions> =
159+
| PluginEntry
160+
| ((options: T, ctx: Context) => PluginEntry);

0 commit comments

Comments
 (0)