@docusaurus/types 2.0.0-beta.2 → 2.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/package.json +10 -6
  2. package/src/index.d.ts +613 -282
  3. package/src/index.js +0 -10
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "@docusaurus/types",
3
- "version": "2.0.0-beta.2",
3
+ "version": "2.0.0-beta.20",
4
4
  "description": "Common types for Docusaurus packages.",
5
- "main": "./src/index.js",
6
5
  "types": "./src/index.d.ts",
7
6
  "publishConfig": {
8
7
  "access": "public"
@@ -13,12 +12,17 @@
13
12
  "directory": "packages/docusaurus-types"
14
13
  },
15
14
  "license": "MIT",
15
+ "scripts": {
16
+ "test": "tsc -p ."
17
+ },
16
18
  "dependencies": {
17
19
  "commander": "^5.1.0",
18
- "joi": "^17.4.0",
19
- "querystring": "0.2.0",
20
- "webpack": "^5.40.0",
20
+ "history": "^4.9.0",
21
+ "joi": "^17.6.0",
22
+ "react-helmet-async": "^1.3.0",
23
+ "utility-types": "^3.10.0",
24
+ "webpack": "^5.72.0",
21
25
  "webpack-merge": "^5.8.0"
22
26
  },
23
- "gitHead": "883f07fddffaf1657407c8e202e370cc436e25f7"
27
+ "gitHead": "ed5cdba401a5948e187e927039b142a0decc702d"
24
28
  }
package/src/index.d.ts CHANGED
@@ -5,78 +5,353 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- // ESLint doesn't understand types dependencies in d.ts
9
- // eslint-disable-next-line import/no-extraneous-dependencies
10
- import type {RuleSetRule, Configuration} from 'webpack';
11
- import type {Command} from 'commander';
8
+ import type {RuleSetRule, Configuration as WebpackConfiguration} from 'webpack';
9
+ import type {CustomizeRuleString} from 'webpack-merge/dist/types';
10
+ import type {CommanderStatic} from 'commander';
12
11
  import type {ParsedUrlQueryInput} from 'querystring';
13
12
  import type Joi from 'joi';
13
+ import type {HelmetServerState} from 'react-helmet-async';
14
+ import type {
15
+ DeepRequired,
16
+ Required as RequireKeys,
17
+ DeepPartial,
18
+ } from 'utility-types';
19
+ import type {Location} from 'history';
14
20
 
15
- // Convert webpack-merge webpack-merge enum to union type
16
- // For type retro-compatible webpack-merge upgrade: we used string literals before)
17
- // see https://github.com/survivejs/webpack-merge/issues/179
18
- type MergeStrategy = 'match' | 'merge' | 'append' | 'prepend' | 'replace';
21
+ // === Configuration ===
19
22
 
20
23
  export type ReportingSeverity = 'ignore' | 'log' | 'warn' | 'error' | 'throw';
21
24
 
25
+ export type PluginOptions = {id?: string} & {[key: string]: unknown};
26
+
27
+ export type PluginConfig =
28
+ | string
29
+ | [string, PluginOptions]
30
+ | [PluginModule, PluginOptions]
31
+ | PluginModule
32
+ | false
33
+ | null;
34
+
35
+ export type PresetConfig =
36
+ | string
37
+ | [string, {[key: string]: unknown}]
38
+ | false
39
+ | null;
40
+
22
41
  export type ThemeConfig = {
23
42
  [key: string]: unknown;
24
43
  };
25
44
 
26
- export interface DocusaurusConfig {
27
- baseUrl: string;
28
- baseUrlIssueBanner: boolean;
29
- favicon?: string;
30
- tagline?: string;
45
+ export type I18nLocaleConfig = {
46
+ /** The label displayed for this locale in the locales dropdown. */
47
+ label: string;
48
+ /**
49
+ * BCP 47 language tag to use in `<html lang="...">` and in
50
+ * `<link ... hreflang="...">`
51
+ */
52
+ htmlLang: string;
53
+ /** Used to select the locale's CSS and html meta attribute. */
54
+ direction: 'ltr' | 'rtl';
55
+ /**
56
+ * The [calendar](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar)
57
+ * used to calculate the date era. Note that it doesn't control the actual
58
+ * string displayed: `MM/DD/YYYY` and `DD/MM/YYYY` are both gregory. To choose
59
+ * the format (`DD/MM/YYYY` or `MM/DD/YYYY`), set your locale name to `en-GB`
60
+ * or `en-US` (`en` means `en-US`).
61
+ */
62
+ calendar: string;
63
+ };
64
+
65
+ export type I18nConfig = {
66
+ /**
67
+ * The locale that:
68
+ * 1. Does not have its name in the base URL
69
+ * 2. Gets started with `docusaurus start` without `--locale` option
70
+ * 3. Will be used for the `<link hrefLang="x-default">` tag
71
+ */
72
+ defaultLocale: string;
73
+ /** List of locales deployed on your site. Must contain `defaultLocale`. */
74
+ locales: [string, ...string[]];
75
+ /** Individual options for each locale. */
76
+ localeConfigs: {[locale: string]: Partial<I18nLocaleConfig>};
77
+ };
78
+
79
+ /**
80
+ * Docusaurus config, after validation/normalization.
81
+ */
82
+ export type DocusaurusConfig = {
83
+ /**
84
+ * Title for your website. Will be used in metadata and as browser tab title.
85
+ *
86
+ * @see https://docusaurus.io/docs/api/docusaurus-config#title
87
+ */
31
88
  title: string;
89
+ /**
90
+ * URL for your website. This can also be considered the top-level hostname.
91
+ * For example, `https://facebook.github.io` is the URL of
92
+ * https://facebook.github.io/metro/, and `https://docusaurus.io` is the URL
93
+ * for https://docusaurus.io.
94
+ *
95
+ * @see https://docusaurus.io/docs/api/docusaurus-config#url
96
+ */
32
97
  url: string;
33
- // trailingSlash undefined = legacy retrocompatible behavior => /file => /file/index.html
98
+ /**
99
+ * Can be considered as the path after the host. For example, `/metro/` is the
100
+ * base URL of https://facebook.github.io/metro/. For URLs that have no path,
101
+ * it should be set to `/`. Always has both leading and trailing slash.
102
+ *
103
+ * @see https://docusaurus.io/docs/api/docusaurus-config#baseUrl
104
+ */
105
+ baseUrl: string;
106
+ /**
107
+ * Path to your site favicon; must be a URL that can be used in link's href.
108
+ *
109
+ * @see https://docusaurus.io/docs/api/docusaurus-config#favicon
110
+ */
111
+ favicon?: string;
112
+ /**
113
+ * Allow to customize the presence/absence of a trailing slash at the end of
114
+ * URLs/links, and how static HTML files are generated:
115
+ *
116
+ * - `undefined` (default): keeps URLs untouched, and emit
117
+ * `/docs/myDoc/index.html` for `/docs/myDoc.md`
118
+ * - `true`: add trailing slashes to URLs/links, and emit
119
+ * `/docs/myDoc/index.html` for `/docs/myDoc.md`
120
+ * - `false`: remove trailing slashes from URLs/links, and emit
121
+ * `/docs/myDoc.html` for `/docs/myDoc.md`
122
+ *
123
+ * @see https://github.com/slorber/trailing-slash-guide
124
+ * @see https://docusaurus.io/docs/api/docusaurus-config#trailingSlash
125
+ * @default undefined
126
+ */
34
127
  trailingSlash: boolean | undefined;
128
+ /**
129
+ * The i18n configuration object to [localize your
130
+ * site](https://docusaurus.io/docs/i18n/introduction).
131
+ *
132
+ * @see https://docusaurus.io/docs/api/docusaurus-config#i18n
133
+ */
35
134
  i18n: I18nConfig;
135
+ /**
136
+ * This option adds `<meta name="robots" content="noindex, nofollow">` to
137
+ * every page to tell search engines to avoid indexing your site.
138
+ *
139
+ * @see https://moz.com/learn/seo/robots-meta-directives
140
+ * @see https://docusaurus.io/docs/api/docusaurus-config#noIndex
141
+ * @default false
142
+ */
143
+ noIndex: boolean;
144
+ /**
145
+ * The behavior of Docusaurus when it detects any broken link.
146
+ *
147
+ * @see https://docusaurus.io/docs/api/docusaurus-config#onBrokenLinks
148
+ * @default "throw"
149
+ */
36
150
  onBrokenLinks: ReportingSeverity;
151
+ /**
152
+ * The behavior of Docusaurus when it detects any broken markdown link.
153
+ *
154
+ * @see https://docusaurus.io/docs/api/docusaurus-config#onBrokenMarkdownLinks
155
+ * @default "warn"
156
+ */
37
157
  onBrokenMarkdownLinks: ReportingSeverity;
158
+ /**
159
+ * The behavior of Docusaurus when it detects any [duplicate
160
+ * routes](https://docusaurus.io/docs/creating-pages#duplicate-routes).
161
+ *
162
+ * @see https://docusaurus.io/docs/api/docusaurus-config#onDuplicateRoutes
163
+ * @default "warn"
164
+ */
38
165
  onDuplicateRoutes: ReportingSeverity;
39
- noIndex: boolean;
166
+ /**
167
+ * The tagline for your website.
168
+ *
169
+ * @see https://docusaurus.io/docs/api/docusaurus-config#tagline
170
+ * @default ""
171
+ */
172
+ tagline: string;
173
+ /**
174
+ * The GitHub user or organization that owns the repository. You don't need
175
+ * this if you are not using the `docusaurus deploy` command.
176
+ *
177
+ * @see https://docusaurus.io/docs/api/docusaurus-config#organizationName
178
+ */
40
179
  organizationName?: string;
180
+ /**
181
+ * The name of the GitHub repository. You don't need this if you are not using
182
+ * the `docusaurus deploy` command.
183
+ *
184
+ * @see https://docusaurus.io/docs/api/docusaurus-config#projectName
185
+ */
41
186
  projectName?: string;
187
+ /**
188
+ * The name of the branch to deploy the static files to. You don't need this
189
+ * if you are not using the `docusaurus deploy` command.
190
+ *
191
+ * @see https://docusaurus.io/docs/api/docusaurus-config#deploymentBranch
192
+ */
193
+ deploymentBranch?: string;
194
+ /**
195
+ * The hostname of your server. Useful if you are using GitHub Enterprise. You
196
+ * don't need this if you are not using the `docusaurus deploy` command.
197
+ *
198
+ * @see https://docusaurus.io/docs/api/docusaurus-config#githubHost
199
+ */
42
200
  githubHost?: string;
201
+ /**
202
+ * The port of your server. Useful if you are using GitHub Enterprise. You
203
+ * don't need this if you are not using the `docusaurus deploy` command.
204
+ *
205
+ * @see https://docusaurus.io/docs/api/docusaurus-config#githubPort
206
+ */
43
207
  githubPort?: string;
44
- plugins?: PluginConfig[];
45
- themes?: PluginConfig[];
46
- presets?: PresetConfig[];
208
+ /**
209
+ * The [theme configuration](https://docusaurus.io/docs/api/themes/configuration)
210
+ * object to customize your site UI like navbar and footer.
211
+ *
212
+ * @see https://docusaurus.io/docs/api/docusaurus-config#themeConfig
213
+ * @default {}
214
+ */
47
215
  themeConfig: ThemeConfig;
216
+ /**
217
+ * List of plugins.
218
+ *
219
+ * @see https://docusaurus.io/docs/api/docusaurus-config#plugins
220
+ * @default []
221
+ */
222
+ plugins: PluginConfig[];
223
+ /**
224
+ * List of themes.
225
+ *
226
+ * @see https://docusaurus.io/docs/api/docusaurus-config#themes
227
+ * @default []
228
+ */
229
+ themes: PluginConfig[];
230
+ /**
231
+ * List of presets.
232
+ *
233
+ * @see https://docusaurus.io/docs/api/docusaurus-config#presets
234
+ * @default []
235
+ */
236
+ presets: PresetConfig[];
237
+ /**
238
+ * Docusaurus guards `docusaurus.config.js` from unknown fields. To add a
239
+ * custom field, define it on `customFields`.
240
+ *
241
+ * @see https://docusaurus.io/docs/api/docusaurus-config#customFields
242
+ * @default {}
243
+ */
48
244
  customFields?: {
49
245
  [key: string]: unknown;
50
246
  };
51
- scripts?: (
247
+ /**
248
+ * An array of paths, relative to the site's directory or absolute. Files
249
+ * under these paths will be copied to the build output as-is.
250
+ *
251
+ * @see https://docusaurus.io/docs/api/docusaurus-config#staticDirectories
252
+ * @default ["static"]
253
+ */
254
+ staticDirectories: string[];
255
+ /**
256
+ * An array of scripts to load. The values can be either strings or plain
257
+ * objects of attribute-value maps. The `<script>` tags will be inserted in
258
+ * the HTML `<head>`.
259
+ *
260
+ * Note that `<script>` added here are render-blocking, so you might want to
261
+ * add `async: true`/`defer: true` to the objects.
262
+ *
263
+ * @see https://docusaurus.io/docs/api/docusaurus-config#scripts
264
+ * @default []
265
+ */
266
+ scripts: (
52
267
  | string
53
268
  | {
54
269
  src: string;
55
- [key: string]: unknown;
270
+ [key: string]: string | boolean | undefined;
56
271
  }
57
272
  )[];
58
- clientModules?: string[];
59
- ssrTemplate?: string;
60
- stylesheets?: (
273
+ /**
274
+ * An array of CSS sources to load. The values can be either strings or plain
275
+ * objects of attribute-value maps. The `<link>` tags will be inserted in the
276
+ * HTML `<head>`.
277
+ *
278
+ * @see https://docusaurus.io/docs/api/docusaurus-config#stylesheets
279
+ * @default []
280
+ */
281
+ stylesheets: (
61
282
  | string
62
283
  | {
63
284
  href: string;
64
- [key: string]: unknown;
285
+ [key: string]: string | boolean | undefined;
65
286
  }
66
287
  )[];
67
- titleDelimiter?: string;
288
+ /**
289
+ * An array of [client modules](https://docusaurus.io/docs/advanced/client#client-modules)
290
+ * to load globally on your site.
291
+ *
292
+ * @see https://docusaurus.io/docs/api/docusaurus-config#clientModules
293
+ * @default []
294
+ */
295
+ clientModules: string[];
296
+ /**
297
+ * An HTML template written in [Eta's syntax](https://eta.js.org/docs/syntax#syntax-overview)
298
+ * that will be used to render your application. This can be used to set
299
+ * custom attributes on the `body` tags, additional `meta` tags, customize the
300
+ * `viewport`, etc. Please note that Docusaurus will rely on the template to
301
+ * be correctly structured in order to function properly, once you do
302
+ * customize it, you will have to make sure that your template is compliant
303
+ * with the requirements from upstream.
304
+ *
305
+ * @see https://docusaurus.io/docs/api/docusaurus-config#ssrTemplate
306
+ */
307
+ ssrTemplate?: string;
308
+ /**
309
+ * Will be used as title delimiter in the generated `<title>` tag.
310
+ *
311
+ * @see https://docusaurus.io/docs/api/docusaurus-config#titleDelimiter
312
+ * @default "|"
313
+ */
314
+ titleDelimiter: string;
315
+ /**
316
+ * When enabled, will show a banner in case your site can't load its CSS or
317
+ * JavaScript files, which is a very common issue, often related to a wrong
318
+ * `baseUrl` in site config.
319
+ *
320
+ * @see https://docusaurus.io/docs/api/docusaurus-config#baseUrlIssueBanner
321
+ * @default true
322
+ */
323
+ baseUrlIssueBanner: boolean;
324
+ /** Webpack-related options. */
68
325
  webpack?: {
326
+ /**
327
+ * Configuration for alternative JS loaders. "babel" will use the built-in
328
+ * Babel loader and preset; otherwise, you can provide your custom Webpack
329
+ * rule set.
330
+ */
69
331
  jsLoader: 'babel' | ((isServer: boolean) => RuleSetRule);
70
332
  };
71
- }
333
+ };
334
+
335
+ /**
336
+ * Docusaurus config, as provided by the user (partial/unnormalized). This type
337
+ * is used to provide type-safety / IDE auto-complete on the config file.
338
+ * @see https://docusaurus.io/docs/typescript-support
339
+ */
340
+ export type Config = RequireKeys<
341
+ DeepPartial<DocusaurusConfig>,
342
+ 'title' | 'url' | 'baseUrl'
343
+ >;
344
+
345
+ // === Data loading ===
72
346
 
73
347
  /**
74
348
  * - `type: 'package'`, plugin is in a different package.
75
349
  * - `type: 'project'`, plugin is in the same docusaurus project.
76
- * - `type: 'local'`, none of plugin's ancestor directory contains any package.json.
350
+ * - `type: 'local'`, none of the plugin's ancestor directories contains a
351
+ * package.json.
77
352
  * - `type: 'synthetic'`, docusaurus generated internal plugin.
78
353
  */
79
- export type DocusaurusPluginVersionInformation =
354
+ export type PluginVersionInformation =
80
355
  | {
81
356
  readonly type: 'package';
82
357
  readonly name?: string;
@@ -86,169 +361,175 @@ export type DocusaurusPluginVersionInformation =
86
361
  | {readonly type: 'local'}
87
362
  | {readonly type: 'synthetic'};
88
363
 
89
- export interface DocusaurusSiteMetadata {
364
+ export type SiteMetadata = {
90
365
  readonly docusaurusVersion: string;
91
366
  readonly siteVersion?: string;
92
- readonly pluginVersions: Record<string, DocusaurusPluginVersionInformation>;
93
- }
94
-
95
- // Inspired by Chrome JSON, because it's a widely supported i18n format
96
- // https://developer.chrome.com/apps/i18n-messages
97
- // https://support.crowdin.com/file-formats/chrome-json/
98
- // https://www.applanga.com/docs/formats/chrome_i18n_json
99
- // https://docs.transifex.com/formats/chrome-json
100
- // https://help.phrase.com/help/chrome-json-messages
101
- export type TranslationMessage = {message: string; description?: string};
102
- export type TranslationFileContent = Record<string, TranslationMessage>;
103
- export type TranslationFile = {path: string; content: TranslationFileContent};
104
- export type TranslationFiles = TranslationFile[];
105
-
106
- export type I18nLocaleConfig = {
107
- label: string;
108
- direction: string;
109
- };
110
-
111
- export type I18nConfig = {
112
- defaultLocale: string;
113
- locales: [string, ...string[]];
114
- localeConfigs: Record<string, Partial<I18nLocaleConfig>>;
115
- };
116
-
117
- export type I18n = {
118
- defaultLocale: string;
119
- locales: [string, ...string[]];
120
- currentLocale: string;
121
- localeConfigs: Record<string, I18nLocaleConfig>;
367
+ readonly pluginVersions: {[pluginName: string]: PluginVersionInformation};
122
368
  };
123
369
 
124
- export interface DocusaurusContext {
125
- siteConfig: DocusaurusConfig;
126
- siteMetadata: DocusaurusSiteMetadata;
127
- globalData: Record<string, unknown>;
128
- i18n: I18n;
129
- codeTranslations: Record<string, string>;
130
- isClient: boolean;
131
- }
132
-
133
- export interface Preset {
134
- plugins?: PluginConfig[];
135
- themes?: PluginConfig[];
136
- }
137
-
138
- export type PresetConfig =
139
- | [string, Record<string, unknown>]
140
- | [string]
141
- | string;
142
-
143
- export type HostPortCLIOptions = {
144
- host?: string;
145
- port?: string;
370
+ /**
371
+ * Inspired by Chrome JSON, because it's a widely supported i18n format
372
+ * @see https://developer.chrome.com/apps/i18n-messages
373
+ * @see https://support.crowdin.com/file-formats/chrome-json/
374
+ * @see https://www.applanga.com/docs/formats/chrome_i18n_json
375
+ * @see https://docs.transifex.com/formats/chrome-json
376
+ * @see https://help.phrase.com/help/chrome-json-messages
377
+ */
378
+ export type TranslationMessage = {message: string; description?: string};
379
+ export type TranslationFileContent = {[msgId: string]: TranslationMessage};
380
+ /**
381
+ * An abstract representation of how a translation file exists on disk. The core
382
+ * would handle the file reading/writing; plugins just need to deal with
383
+ * translations in-memory.
384
+ */
385
+ export type TranslationFile = {
386
+ /**
387
+ * Relative to the directory where it's expected to be found. For plugin
388
+ * files, it's relative to `i18n/<locale>/<pluginName>/<pluginId>`. Should NOT
389
+ * have any extension.
390
+ */
391
+ path: string;
392
+ content: TranslationFileContent;
146
393
  };
147
394
 
148
- export type ConfigOptions = {
149
- config: string;
150
- };
395
+ export type I18n = DeepRequired<I18nConfig> & {currentLocale: string};
151
396
 
152
- export type StartCLIOptions = HostPortCLIOptions &
153
- ConfigOptions & {
154
- hotOnly: boolean;
155
- open: boolean;
156
- poll: boolean | number;
157
- locale?: string;
158
- };
397
+ export type GlobalData = {[pluginName: string]: {[pluginId: string]: unknown}};
159
398
 
160
- export type ServeCLIOptions = HostPortCLIOptions &
161
- ConfigOptions & {
162
- dir: string;
163
- build: boolean;
164
- };
399
+ export type CodeTranslations = {[msgId: string]: string};
165
400
 
166
- export type BuildOptions = ConfigOptions & {
167
- bundleAnalyzer: boolean;
168
- outDir: string;
169
- minify: boolean;
170
- skipBuild: boolean;
171
- };
401
+ export type DocusaurusContext = {
402
+ siteConfig: DocusaurusConfig;
403
+ siteMetadata: SiteMetadata;
404
+ globalData: GlobalData;
405
+ i18n: I18n;
406
+ codeTranslations: CodeTranslations;
172
407
 
173
- export type BuildCLIOptions = BuildOptions & {
174
- locale?: string;
408
+ // Don't put mutable values here, to avoid triggering re-renders
409
+ // We could reconsider that choice if context selectors are implemented
410
+ // isBrowser: boolean; // Not here on purpose!
175
411
  };
176
412
 
177
- export interface LoadContext {
413
+ export type LoadContext = {
178
414
  siteDir: string;
179
415
  generatedFilesDir: string;
180
416
  siteConfig: DocusaurusConfig;
181
417
  siteConfigPath: string;
182
418
  outDir: string;
419
+ /**
420
+ * Duplicated from `siteConfig.baseUrl`, but probably worth keeping. We mutate
421
+ * `siteConfig` to make `baseUrl` there localized as well, but that's mostly
422
+ * for client-side. `context.baseUrl` is still more convenient for plugins.
423
+ */
183
424
  baseUrl: string;
184
425
  i18n: I18n;
185
- ssrTemplate?: string;
186
- codeTranslations: Record<string, string>;
187
- }
426
+ codeTranslations: CodeTranslations;
427
+ };
188
428
 
189
- export interface InjectedHtmlTags {
429
+ export type Props = LoadContext & {
190
430
  headTags: string;
191
431
  preBodyTags: string;
192
432
  postBodyTags: string;
193
- }
194
-
195
- export type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[];
196
-
197
- export interface Props extends LoadContext, InjectedHtmlTags {
198
- siteMetadata: DocusaurusSiteMetadata;
433
+ siteMetadata: SiteMetadata;
199
434
  routes: RouteConfig[];
200
435
  routesPaths: string[];
201
- plugins: LoadedPlugin<unknown>[];
202
- }
203
-
204
- export interface PluginContentLoadedActions {
205
- addRoute(config: RouteConfig): void;
206
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
207
- createData(name: string, data: any): Promise<string>;
208
- setGlobalData<T = unknown>(data: T): void;
209
- }
210
-
211
- export type AllContent = Record<
212
- string, // plugin name
213
- Record<
214
- string, // plugin id
215
- unknown // plugin data
216
- >
217
- >;
436
+ plugins: LoadedPlugin[];
437
+ };
438
+
439
+ // === Plugin ===
440
+
441
+ export type PluginContentLoadedActions = {
442
+ addRoute: (config: RouteConfig) => void;
443
+ createData: (name: string, data: string) => Promise<string>;
444
+ setGlobalData: (data: unknown) => void;
445
+ };
446
+
447
+ export type ConfigureWebpackUtils = {
448
+ getStyleLoaders: (
449
+ isServer: boolean,
450
+ cssOptions: {[key: string]: unknown},
451
+ ) => RuleSetRule[];
452
+ getJSLoader: (options: {
453
+ isServer: boolean;
454
+ babelOptions?: {[key: string]: unknown};
455
+ }) => RuleSetRule;
456
+ };
457
+
458
+ export type AllContent = {
459
+ [pluginName: string]: {
460
+ [pluginID: string]: unknown;
461
+ };
462
+ };
218
463
 
219
464
  // TODO improve type (not exposed by postcss-loader)
220
- export type PostCssOptions = Record<string, unknown> & {plugins: unknown[]};
465
+ export type PostCssOptions = {plugins: unknown[]; [key: string]: unknown};
221
466
 
222
- export interface Plugin<Content> {
467
+ type HtmlTagObject = {
468
+ /**
469
+ * Attributes of the html tag.
470
+ * E.g. `{ disabled: true, value: "demo", rel: "preconnect" }`
471
+ */
472
+ attributes?: Partial<{[key: string]: string | boolean}>;
473
+ /** The tag name, e.g. `div`, `script`, `link`, `meta` */
474
+ tagName: string;
475
+ /** The inner HTML */
476
+ innerHTML?: string;
477
+ };
478
+
479
+ export type HtmlTags = string | HtmlTagObject | (string | HtmlTagObject)[];
480
+
481
+ export type ValidationSchema<T> = Joi.ObjectSchema<T>;
482
+
483
+ export type Validate<T, U> = (
484
+ validationSchema: ValidationSchema<U>,
485
+ options: T,
486
+ ) => U;
487
+
488
+ export type OptionValidationContext<T, U> = {
489
+ validate: Validate<T, U>;
490
+ options: T;
491
+ };
492
+
493
+ export type ThemeConfigValidationContext<T> = {
494
+ validate: Validate<T, T>;
495
+ themeConfig: Partial<T>;
496
+ };
497
+
498
+ export type Plugin<Content = unknown> = {
223
499
  name: string;
224
- loadContent?(): Promise<Content>;
225
- contentLoaded?({
226
- content,
227
- actions,
228
- }: {
229
- content: Content; // the content loaded by this plugin instance
230
- allContent: AllContent; // content loaded by ALL the plugins
500
+ loadContent?: () => Promise<Content> | Content;
501
+ contentLoaded?: (args: {
502
+ /** The content loaded by this plugin instance */
503
+ content: Content; //
504
+ /** Content loaded by ALL the plugins */
505
+ allContent: AllContent;
231
506
  actions: PluginContentLoadedActions;
232
- }): void;
233
- routesLoaded?(routes: RouteConfig[]): void; // TODO remove soon, deprecated (alpha-60)
234
- postBuild?(props: Props): void;
235
- postStart?(props: Props): void;
236
- // TODO refactor the configureWebpack API surface: use an object instead of multiple params (requires breaking change)
237
- configureWebpack?(
238
- config: Configuration,
507
+ }) => Promise<void> | void;
508
+ postBuild?: (
509
+ props: Props & {
510
+ content: Content;
511
+ head: {[location: string]: HelmetServerState};
512
+ },
513
+ ) => Promise<void> | void;
514
+ // TODO refactor the configureWebpack API surface: use an object instead of
515
+ // multiple params (requires breaking change)
516
+ configureWebpack?: (
517
+ config: WebpackConfiguration,
239
518
  isServer: boolean,
240
519
  utils: ConfigureWebpackUtils,
241
520
  content: Content,
242
- ): Configuration & {mergeStrategy?: ConfigureWebpackFnMergeStrategy};
243
- configurePostCss?(options: PostCssOptions): PostCssOptions;
244
- getThemePath?(): string;
245
- getTypeScriptThemePath?(): string;
246
- getPathsToWatch?(): string[];
247
- getClientModules?(): string[];
248
- extendCli?(cli: Command): void;
249
- injectHtmlTags?({
250
- content: Content,
251
- }): {
521
+ ) => WebpackConfiguration & {
522
+ mergeStrategy?: {
523
+ [key: string]: CustomizeRuleString;
524
+ };
525
+ };
526
+ configurePostCss?: (options: PostCssOptions) => PostCssOptions;
527
+ getThemePath?: () => string;
528
+ getTypeScriptThemePath?: () => string;
529
+ getPathsToWatch?: () => string[];
530
+ getClientModules?: () => string[];
531
+ extendCli?: (cli: CommanderStatic) => void;
532
+ injectHtmlTags?: (args: {content: Content}) => {
252
533
  headTags?: HtmlTags;
253
534
  preBodyTags?: HtmlTags;
254
535
  postBodyTags?: HtmlTags;
@@ -256,163 +537,213 @@ export interface Plugin<Content> {
256
537
  // TODO before/afterDevServer implementation
257
538
 
258
539
  // translations
259
- getTranslationFiles?({
260
- content,
261
- }: {
540
+ getTranslationFiles?: (args: {
541
+ content: Content;
542
+ }) => Promise<TranslationFile[]> | TranslationFile[];
543
+ getDefaultCodeTranslationMessages?: () =>
544
+ | Promise<{[id: string]: string}>
545
+ | {[id: string]: string};
546
+ translateContent?: (args: {
547
+ /** The content loaded by this plugin instance. */
262
548
  content: Content;
263
- }): Promise<TranslationFiles>;
264
- getDefaultCodeTranslationMessages?(): Promise<
265
- Record<
266
- string, // id
267
- string // message
268
- >
269
- >;
270
- translateContent?({
271
- content,
272
- translationFiles,
273
- }: {
274
- content: Content; // the content loaded by this plugin instance
275
- translationFiles: TranslationFiles;
276
- }): Content;
277
- translateThemeConfig?({
278
- themeConfig,
279
- translationFiles,
280
- }: {
549
+ translationFiles: TranslationFile[];
550
+ }) => Content;
551
+ translateThemeConfig?: (args: {
281
552
  themeConfig: ThemeConfig;
282
- translationFiles: TranslationFiles;
283
- }): ThemeConfig;
284
- }
553
+ translationFiles: TranslationFile[];
554
+ }) => ThemeConfig;
555
+ };
556
+
557
+ export type InitializedPlugin = Plugin & {
558
+ readonly options: Required<PluginOptions>;
559
+ readonly version: PluginVersionInformation;
560
+ /** The absolute path to the folder containing the entry point file. */
561
+ readonly path: string;
562
+ };
285
563
 
286
- export type InitializedPlugin = Plugin<unknown> & {
287
- readonly options: PluginOptions;
288
- readonly version: DocusaurusPluginVersionInformation;
564
+ export type LoadedPlugin = InitializedPlugin & {
565
+ readonly content: unknown;
289
566
  };
290
567
 
291
- export type LoadedPlugin = InitializedPlugin & {readonly content: unknown};
568
+ export type SwizzleAction = 'eject' | 'wrap';
569
+ export type SwizzleActionStatus = 'safe' | 'unsafe' | 'forbidden';
292
570
 
293
- export type PluginModule = {
294
- <T, X>(context: LoadContext, options: T): Plugin<X>;
295
- validateOptions?<T>(data: OptionValidationContext<T>): T;
296
- validateThemeConfig?<T>(data: ThemeConfigValidationContext<T>): T;
297
- getSwizzleComponentList?(): string[];
571
+ export type SwizzleComponentConfig = {
572
+ actions: {[action in SwizzleAction]: SwizzleActionStatus};
573
+ description?: string;
298
574
  };
299
575
 
300
- export type ImportedPluginModule = PluginModule & {
301
- default?: PluginModule;
576
+ export type SwizzleConfig = {
577
+ components: {[componentName: string]: SwizzleComponentConfig};
578
+ // Other settings could be added here, like the ability to declare the config
579
+ // as exhaustive so that we can emit errors
302
580
  };
303
581
 
304
- export type ConfigureWebpackFn = Plugin<unknown>['configureWebpack'];
305
- export type ConfigureWebpackFnMergeStrategy = Record<string, MergeStrategy>;
306
- export type ConfigurePostCssFn = Plugin<unknown>['configurePostCss'];
582
+ export type PluginModule = {
583
+ (context: LoadContext, options: unknown): Plugin | Promise<Plugin>;
584
+ validateOptions?: <T, U>(data: OptionValidationContext<T, U>) => U;
585
+ validateThemeConfig?: <T>(data: ThemeConfigValidationContext<T>) => T;
307
586
 
308
- export type PluginOptions = {id?: string} & Record<string, unknown>;
587
+ getSwizzleComponentList?: () => string[] | undefined; // TODO deprecate this one later
588
+ getSwizzleConfig?: () => SwizzleConfig | undefined;
589
+ };
309
590
 
310
- export type PluginConfig =
311
- | [string, PluginOptions]
312
- | [string]
313
- | string
314
- | [PluginModule, PluginOptions]
315
- | PluginModule;
591
+ export type Preset = {
592
+ plugins?: PluginConfig[];
593
+ themes?: PluginConfig[];
594
+ };
595
+
596
+ export type PresetModule = {
597
+ (context: LoadContext, presetOptions: unknown): Preset;
598
+ };
316
599
 
317
- export interface ChunkRegistry {
318
- loader: string;
319
- modulePath: string;
320
- }
600
+ // === Route registry ===
321
601
 
602
+ /**
603
+ * A "module" represents a unit of serialized data emitted from the plugin. It
604
+ * will be imported on client-side and passed as props, context, etc.
605
+ *
606
+ * If it's a string, it's a file path that Webpack can `require`; if it's
607
+ * an object, it can also contain `query` or other metadata.
608
+ */
322
609
  export type Module =
323
610
  | {
324
- path: string;
611
+ /**
612
+ * A marker that tells the route generator this is an import and not a
613
+ * nested object to recurse.
614
+ */
325
615
  __import?: boolean;
616
+ path: string;
326
617
  query?: ParsedUrlQueryInput;
327
618
  }
328
619
  | string;
329
620
 
330
- export interface RouteModule {
331
- [module: string]: Module | RouteModule | RouteModule[];
332
- }
333
-
334
- export interface ChunkNames {
335
- [name: string]: string | null | ChunkNames | ChunkNames[];
336
- }
621
+ /**
622
+ * Represents the data attached to each route. Since the routes.js is a
623
+ * monolithic data file, any data (like props) should be serialized separately
624
+ * and registered here as file paths (a {@link Module}), so that we could
625
+ * code-split.
626
+ */
627
+ export type RouteModules = {
628
+ [propName: string]: Module | RouteModules | RouteModules[];
629
+ };
337
630
 
338
- export interface RouteConfig {
631
+ /**
632
+ * Represents a "slice" of the final route structure returned from the plugin
633
+ * `addRoute` action.
634
+ */
635
+ export type RouteConfig = {
636
+ /** With leading slash. Trailing slash will be normalized by config. */
339
637
  path: string;
638
+ /** Component used to render this route, a path that Webpack can `require`. */
340
639
  component: string;
341
- modules?: RouteModule;
342
- routes?: RouteConfig[];
343
- exact?: boolean;
344
- priority?: number;
345
- }
346
-
347
- // Aliases used for Webpack resolution (when using docusaurus swizzle)
348
- export interface ThemeAliases {
349
- [alias: string]: string;
350
- }
351
-
352
- export interface ConfigureWebpackUtils {
353
- getStyleLoaders: (
354
- isServer: boolean,
355
- cssOptions: {
356
- [key: string]: unknown;
357
- },
358
- ) => RuleSetRule[];
359
- getJSLoader: (options: {
360
- isServer: boolean;
361
- babelOptions?: Record<string, unknown>;
362
- }) => RuleSetRule;
363
-
364
- // TODO deprecated: remove before end of 2021?
365
- getCacheLoader: (
366
- isServer: boolean,
367
- cacheOptions?: Record<string, unknown>,
368
- ) => RuleSetRule | null;
369
-
370
- // TODO deprecated: remove before end of 2021?
371
- getBabelLoader: (
372
- isServer: boolean,
373
- options?: Record<string, unknown>,
374
- ) => RuleSetRule;
375
- }
376
-
377
- interface HtmlTagObject {
378
640
  /**
379
- * Attributes of the html tag
380
- * E.g. `{'disabled': true, 'value': 'demo', 'rel': 'preconnect'}`
641
+ * Props. Each entry should be `[propName]: pathToPropModule` (created with
642
+ * `createData`)
381
643
  */
382
- attributes?: {
383
- [attributeName: string]: string | boolean;
384
- };
644
+ modules?: RouteModules;
385
645
  /**
386
- * The tag name e.g. `div`, `script`, `link`, `meta`
646
+ * The route context will wrap the `component`. Use `useRouteContext` to
647
+ * retrieve what's declared here. Note that all custom route context declared
648
+ * here will be namespaced under {@link RouteContext.data}.
387
649
  */
388
- tagName: string;
650
+ context?: RouteModules;
651
+ /** Nested routes config. */
652
+ routes?: RouteConfig[];
653
+ /** React router config option: `exact` routes would not match subroutes. */
654
+ exact?: boolean;
655
+ /** Used to sort routes. Higher-priority routes will be placed first. */
656
+ priority?: number;
657
+ /** Extra props; will be copied to routes.js. */
658
+ [propName: string]: unknown;
659
+ };
660
+
661
+ export type RouteContext = {
389
662
  /**
390
- * The inner HTML
663
+ * Plugin-specific context data.
391
664
  */
392
- innerHTML?: string;
393
- }
665
+ data?: object | undefined;
666
+ };
394
667
 
395
- export type ValidationResult<T> = T;
668
+ /**
669
+ * Top-level plugin routes automatically add some context data to the route.
670
+ * This permits us to know which plugin is handling the current route.
671
+ */
672
+ export type PluginRouteContext = RouteContext & {
673
+ plugin: {
674
+ id: string;
675
+ name: string;
676
+ };
677
+ };
396
678
 
397
- export type ValidationSchema<T> = Joi.ObjectSchema<T>;
679
+ /**
680
+ * The shape would be isomorphic to {@link RouteModules}:
681
+ * {@link Module} -> `string`, `RouteModules[]` -> `ChunkNames[]`.
682
+ *
683
+ * Each `string` chunk name will correlate with one key in the {@link Registry}.
684
+ */
685
+ export type ChunkNames = {
686
+ [propName: string]: string | ChunkNames | ChunkNames[];
687
+ };
398
688
 
399
- export type Validate<T> = (
400
- validationSchema: ValidationSchema<T>,
401
- options: Partial<T>,
402
- ) => ValidationResult<T>;
689
+ /**
690
+ * A map from route paths (with a hash) to the chunk names of each module, which
691
+ * the bundler will collect.
692
+ *
693
+ * Chunk keys are routes with a hash, because 2 routes can conflict with each
694
+ * other if they have the same path, e.g.: parent=/docs, child=/docs
695
+ *
696
+ * @see https://github.com/facebook/docusaurus/issues/2917
697
+ */
698
+ export type RouteChunkNames = {
699
+ [routePathHashed: string]: ChunkNames;
700
+ };
403
701
 
404
- export interface OptionValidationContext<T> {
405
- validate: Validate<T>;
406
- options: Partial<T>;
407
- }
702
+ /**
703
+ * Each key is the chunk name, which you can get from `routeChunkNames` (see
704
+ * {@link RouteChunkNames}). The values are the opts data that react-loadable
705
+ * needs. For example:
706
+ *
707
+ * ```js
708
+ * const options = {
709
+ * optsLoader: {
710
+ * component: () => import('./Pages.js'),
711
+ * content.foo: () => import('./doc1.md'),
712
+ * },
713
+ * optsModules: ['./Pages.js', './doc1.md'],
714
+ * optsWebpack: [
715
+ * require.resolveWeak('./Pages.js'),
716
+ * require.resolveWeak('./doc1.md'),
717
+ * ],
718
+ * }
719
+ * ```
720
+ *
721
+ * @see https://github.com/jamiebuilds/react-loadable#declaring-which-modules-are-being-loaded
722
+ */
723
+ export type Registry = {
724
+ readonly [chunkName: string]: [
725
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
726
+ Loader: () => Promise<any>,
727
+ ModuleName: string,
728
+ ResolvedModuleName: string,
729
+ ];
730
+ };
408
731
 
409
- export interface ThemeConfigValidationContext<T> {
410
- validate: Validate<T>;
411
- themeConfig: Partial<T>;
412
- }
732
+ export type ClientModule = {
733
+ onRouteDidUpdate?: (args: {
734
+ previousLocation: Location | null;
735
+ location: Location;
736
+ }) => (() => void) | void;
737
+ onRouteUpdate?: (args: {
738
+ previousLocation: Location | null;
739
+ location: Location;
740
+ }) => (() => void) | void;
741
+ };
413
742
 
414
- export interface TOCItem {
415
- readonly value: string;
416
- readonly id: string;
417
- readonly children: TOCItem[];
418
- }
743
+ export type UseDataOptions = {
744
+ /**
745
+ * Throw an error, or simply return undefined if the data cannot be found. Use
746
+ * `true` if you are sure the data must exist.
747
+ */
748
+ failfast?: boolean;
749
+ };
package/src/index.js DELETED
@@ -1,10 +0,0 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- */
7
-
8
- /* eslint-disable */
9
- 'use strict';
10
- Object.defineProperty(exports, '__esModule', {value: true});