master
  1import type { Locales } from '@astral-halo/i18n';
  2
  3// ============================================================================
  4export type Favicon = {
  5  /**
  6   * The URL of the favicon.
  7   *
  8   * favicon 的 URL。
  9   */
 10  src: string;
 11  /**
 12   * The sizes of the favicon.
 13   *
 14   * favicon 的尺寸。
 15   */
 16  sizes?: `${string}x${string}`;
 17};
 18
 19export type ButtonSubConfig<T extends string> = T extends 'text'
 20  ? {
 21      /**
 22       * The text of the button.
 23       *
 24       * 按钮的文本。
 25       */
 26      text: string;
 27      /**
 28       * Extra attributes add to button HTML tag
 29       *
 30       * 添加到按钮 HTML 标签上的额外属性
 31       */
 32      extraAttr?: Record<string, string>;
 33    } & (
 34      | {
 35          /**
 36           * The URL of the button.
 37           *
 38           * 按钮的 URL。
 39           */
 40          href?: string;
 41          /**
 42           * Whether to open the link in a new tab.
 43           *
 44           * 是否在新标签页中打开链接。
 45           *
 46           * @default false
 47           */
 48          blank?: boolean;
 49        }
 50      | {
 51          /**
 52           * The function to be called when the button is clicked.
 53           *
 54           * 当按钮被点击时要调用的函数。
 55           */
 56          onclick?:
 57            | string
 58            | {
 59                id: string;
 60                function: (this: HTMLElement, ev: MouseEvent) => unknown;
 61              };
 62        }
 63    )
 64  : T extends 'icon'
 65    ? {
 66        /**
 67         * The icon of the button. Should be a name of iconify icon.
 68         *
 69         * 按钮的图标。应该是一个 iconify 图标的名称。
 70         */
 71        icon: string;
 72        /**
 73         * The text of the button.
 74         *
 75         * 按钮的文本。
 76         */
 77        text?: string;
 78        /**
 79         * Extra attributes add to button HTML tag
 80         *
 81         * 添加到按钮 HTML 标签上的额外属性
 82         */
 83        extraAttr?: Record<string, string>;
 84      } & (
 85        | {
 86            /**
 87             * The URL of the button.
 88             *
 89             * 按钮的 URL。
 90             */
 91            href?: string;
 92            /**
 93             * Whether to open the link in a new tab.
 94             *
 95             * 是否在新标签页中打开链接。
 96             *
 97             * @default false
 98             */
 99            blank?: boolean;
100          }
101        | {
102            /**
103             * The function to be called when the button is clicked.
104             *
105             * 当按钮被点击时要调用的函数。
106             */
107            onclick?:
108              | string
109              | {
110                  id: string;
111                  function: (this: HTMLElement, ev: MouseEvent) => unknown;
112                };
113          }
114      )
115    : never;
116
117// ============================================================================
118
119export type SiteConfig = {
120  /**
121   * The title of the site.
122   *
123   * 站点的标题。
124   */
125  title: string;
126  /**
127   * The subtitle of the site.
128   *
129   * 站点的副标题。
130   */
131  subtitle: string;
132  /**
133   * The language of the site.
134   *
135   * 站点的语言。
136   */
137  lang: Locales;
138  /**
139   * The time when the site was created.
140   *
141   * 站点建立时间
142   */
143  createAt: Date;
144  /**
145   * The number of posts displayed per page.
146   *
147   * 每页显示的文章数量。
148   */
149  postsPerPage: number;
150  /**
151   * The configuration of the banner.
152   *
153   * 横幅的配置。
154   */
155  banner:
156    | false
157    | {
158        /**
159         * The URL of the banner.
160         *
161         * 横幅的 URL。
162         */
163        src:
164          | string
165          | {
166              /**
167               * URL of the banner in light mode
168               *
169               * 明亮模式下横幅的 URL
170               */
171              light: string;
172              /**
173               * URL of the banner in dark mode
174               *
175               * 暗黑模式下横幅的 URL
176               */
177              dark: string;
178            };
179        /**
180         * The text in the center of homepage banner
181         *
182         * 首页横幅中央的文字
183         *
184         * @default SiteConfig.subtitle
185         */
186        text?: string | null;
187        /**
188         * The height of the banner in homepage.
189         *
190         * 主页中横幅的高度。
191         */
192        homepageHeight: `${number}${'vh' | 'dvh' | 'svh' | 'lvh' | 'rem' | 'px'}`;
193        /**
194         * The height of the banner in post page.
195         *
196         * 文章页面中横幅的高度。
197         */
198        postHeight: `${number}${'vh' | 'dvh' | 'svh' | 'lvh' | 'rem' | 'px'}`;
199        /**
200         * The height of the banner in pages.
201         *
202         * 页面中横幅的高度。
203         */
204        pagesHeight: {
205          /**
206           * The regular expression of the page path.
207           *
208           * 页面路径的正则表达式。
209           */
210          pagePathRegex: RegExp;
211          /**
212           * The height of the banner.
213           *
214           * 横幅的高度。
215           */
216          height: `${number}${'vh' | 'dvh' | 'svh' | 'lvh' | 'rem' | 'px'}`;
217        }[];
218        /**
219         * The default height of the banner.
220         *
221         * 横幅的默认高度。
222         */
223        defaultHeight: `${number}${'vh' | 'dvh' | 'svh' | 'lvh' | 'rem' | 'px'}`;
224      };
225};
226
227export type BuildConfig = {
228  /**
229   * Whether to show drafts on development mode.
230   *
231   * 是否在开发模式下显示草稿。
232   */
233  showDraftsOnDev: boolean;
234  /**
235   * Fetch the size data of remote images during build.
236   *
237   * 在构建时获取远程图像的大小数据。
238   */
239  inferRemoteImageSize: {
240    /**
241     * Whether to enable the feature. Enabling this can reduce cumulative layout shift, but will increase build time.
242     *
243     * 是否开启此功能。开启后,能够减少累计布局位移,但是会增加构建时间。
244     */
245    enable: boolean;
246    /**
247     * The default size of the image. This will be used when the size of the image cannot be fetched or the feature is disabled.
248     *
249     * 图像的默认大小。当无法获取图像的大小或功能被禁用时,将使用此值。
250     */
251    defaultSize: {
252      width: number;
253      height: number;
254    };
255  };
256  /**
257   * Whether to enable image zoom feature.
258   *
259   * 是否启用图像缩放功能。
260   */
261  enableImageZoom: boolean;
262  /**
263   * The name of the light and dark themes.
264   * Should be same as the choosen themes in `src/styles/global.css`
265   *
266   * 浅色和深色主题的名称。
267   * 应与 `src/styles/global.css` 中选择的主题相同。
268   */
269  themeNames: {
270    light: string;
271    dark: string;
272  };
273};
274
275export type ProfileConfig = {
276  /**
277   * The avatar of the profile.
278   *
279   * 头像。
280   */
281  avatar: string;
282  /**
283   * The name of the profile.
284   *
285   * 名字。
286   */
287  name: string;
288  /**
289   * The bio of the profile.
290   *
291   * 简介。
292   */
293  bio?: string;
294  /**
295   * The social links of the profile.
296   *
297   * 社交链接。
298   */
299  socialLinks: {
300    /**
301     * The title of the link.
302     *
303     * 链接的标题。
304     */
305    name: string;
306    /**
307     * The URL of the link.
308     *
309     * 链接的 URL。
310     */
311    url: string;
312    /**
313     * The icon of the link. Should be a name of iconify icon.
314     *
315     * 链接的图标。应该是一个 iconify 图标的名称。
316     */
317    icon: string;
318  }[];
319};
320
321export type LinksConfig = {
322  /**
323   * The items displayed in the links.
324   *
325   * 在友情链接中显示的项目。
326   */
327  items: {
328    /**
329     * The name of the group.
330     *
331     * 组的名称。
332     */
333    groupName: string;
334    /**
335     * The description of the group.
336     *
337     * 组的描述。
338     */
339    groupDescription?: string;
340    /**
341     * The items displayed in the group.
342     *
343     * 在组中显示的项目。
344     */
345    groupItems: {
346      /**
347       * The name of the link.
348       *
349       * 链接的名称。
350       */
351      name: string;
352      /**
353       * The URL of the link.
354       *
355       * 链接的 URL。
356       */
357      url: string;
358      /**
359       * The avatar of the link.
360       *
361       * 链接的头像。
362       */
363      avatar: string;
364      /**
365       * The description of the link.
366       *
367       * 链接的描述。
368       */
369      description?: string;
370    }[];
371  }[];
372};
373
374export type NavbarConfig = {
375  /**
376   * The items displayed in the center of the navbar.
377   *
378   * 在导航栏中间显示的项目。
379   */
380  navbarCenterItems: (
381    | ButtonSubConfig<'text'>
382    | {
383        /**
384         * The title of the group.
385         *
386         * 组的标题。
387         */
388        title: string;
389        /**
390         * The items displayed in the group.
391         *
392         * 在组中显示的项目。
393         */
394        items: ButtonSubConfig<'text'>[];
395      }
396  )[];
397  /**
398   * The items displayed in the right of the navbar.
399   *
400   * 在导航栏右侧显示的项目。
401   */
402  navbarRightItems: {
403    /**
404     * The items displayed only in wide screen (greater than 768px).
405     *
406     * 仅在宽屏幕(大于 768px)显示的项目。
407     */
408    onlyWide: ButtonSubConfig<'icon'>[];
409    /**
410     * The items displayed always.
411     *
412     * 总是显示的项目。
413     */
414    always: ButtonSubConfig<'icon'>[];
415  };
416};
417
418export type FastActionsConfig = {
419  /**
420   * Whether to enable fast actions.
421   *
422   * 是否启用侧边快捷操作按钮。
423   */
424  enable: boolean;
425  /**
426   * The items displayed in fast actions.
427   *
428   * 在侧边快捷操作按钮中显示的项目。
429   */
430  items: ButtonSubConfig<'icon'>[];
431};
432
433export type AsideConfig = {
434  siteInfo: {
435    /**
436     * The contents displayed in the site info.
437     *
438     * 在站点信息中显示的内容。
439     */
440    contents: ('stats' | 'tags')[];
441    /**
442     * The stats displayed in the site info.
443     *
444     * 在站点信息中显示的统计数据。
445     */
446    stats: ('post-count' | 'last-updated' | 'site-words-count' | 'site-run-days')[];
447  };
448  /**
449   * Recent comments card.
450   *
451   * 最近评论卡片
452   */
453  recentComment: {
454    /**
455     * Whether to enable the recent comments card.
456     *
457     * 是否启用最近评论卡片。
458     */
459    enable: boolean;
460    /**
461     * The number of recent comments displayed.
462     *
463     * 显示的最近评论数量。
464     */
465    count: number;
466    /**
467     * Whether to show the avatar of the commenter.
468     *
469     * 是否显示评论者的头像。
470     */
471    showAvatar: boolean;
472  };
473};
474
475export type LicenseConfig = {
476  /**
477   * Whether to enable the license.
478   *
479   * 是否启用许可证。
480   */
481  enable: boolean;
482  /**
483   * The name of the license.
484   *
485   * 许可证的名称。
486   */
487  name: string;
488  /**
489   * The link of the license.
490   *
491   * 许可证的链接。
492   */
493  url: string;
494};
495
496export type FooterConfig = {
497  /**
498   * The columns displayed in the footer. If set to `false`, no columns will be displayed.
499   *
500   * 页脚中显示的列。如果设置为 `false`,则不显示任何列。
501   */
502  columns:
503    | {
504        title: string;
505        items: {
506          text: string;
507          link: string;
508          blank?: boolean;
509        }[];
510      }[]
511    | false;
512  /**
513   * The start year of the copyright.
514   *
515   * 版权开始年份。
516   */
517  copyrightYear: number;
518  /**
519   * The items displayed in the right of the footer.
520   *
521   * 在页脚右侧显示的项目。
522   */
523  rightItems: (string | { text: string; link?: string; class?: string })[][];
524};
525
526export type ArticleConfig = {
527  /**
528   * Whether to enable the table of contents.
529   *
530   * 是否启用目录。
531   */
532  toc: boolean;
533  /**
534   * Whether to enable the word count.
535   *
536   * 是否启用字数统计。
537   */
538  wordCount: boolean;
539  /**
540   * The configuration of the reading time.
541   *
542   * 阅读时间的配置。
543   */
544  readingTime: boolean;
545};
546
547export type SearchConfig = {
548  /**
549   * Whether to enable search.
550   *
551   * 是否启用搜索。
552   */
553  enable: boolean;
554  /**
555   * The provider of the search.
556   *
557   * 搜索的提供者。
558   */
559  provider: 'pagefind';
560};
561
562export type CommentConfig = {
563  /**
564   * Whether to enable comments.
565   *
566   * 是否启用评论。
567   */
568  enable: boolean;
569  /**
570   * The provider of the comments.
571   *
572   * 评论的提供者。
573   */
574  provider: 'twikoo' | 'giscus' | 'waline' | 'artalk';
575  /**
576   * The configuration of Twikoo.
577   *
578   * Twikoo 的配置。
579   *
580   * @see https://twikoo.js.org/
581   */
582  twikoo?: {
583    /**
584     * The envID of Twikoo.
585     *
586     * Twikoo 的 envID。
587     */
588    envId: string;
589    /**
590     * The region of Twikoo backend.
591     *
592     * Twikoo 后端的地区设置。
593     */
594    region?: string;
595  };
596  /**
597   * The configuration of Giscus.
598   *
599   * Giscus 的配置。
600   *
601   * @see https://giscus.app/
602   */
603  giscus?: {
604    /**
605     * The repo used by Giscus.
606     *
607     * Giscus 使用的 repo。
608     */
609    repo: `${string}/${string}`;
610    /**
611     * The repo ID generated by Giscus.
612     *
613     * Giscus 生成的 repo ID。
614     *
615     * @see https://giscus.app/
616     */
617    repoId: string;
618    /**
619     * The category used by Giscus.
620     *
621     * Giscus 使用的 discussion 分类。
622     *
623     * @suggest Announcement
624     */
625    category: string;
626    /**
627     * The category ID generated by Giscus.
628     *
629     * Giscus 生成的分类 ID。
630     *
631     * @see https://giscus.app/
632     */
633    categoryId: string;
634    /**
635     * The mapping of the discussion.
636     *
637     * 讨论的映射。
638     *
639     * @suggest 'og:title'
640     * @see https://giscus.app/
641     */
642    mapping:
643      | 'pathname'
644      | 'url'
645      | 'title'
646      | 'og:title'
647      | {
648          type: 'specific' | 'number';
649          term: string | number;
650        };
651    /**
652     * The theme of Giscus.
653     *
654     * Giscus 的主题。
655     *
656     * @default 'preferred_color_scheme'
657     * @see https://giscus.app/
658     */
659    theme?: string;
660    /**
661     * The position of the comment box.
662     *
663     * 评论框的位置
664     *
665     * @default 'bottom'
666     */
667    inputPosition?: 'top' | 'bottom';
668    /**
669     * Whether to enable reactions.
670     *
671     * 是否启用表情。
672     *
673     * @default false
674     */
675    reactionsEnabled?: boolean;
676    /**
677     * Whether to enable metadata emit.
678     *
679     * 是否启用元数据输出。
680     *
681     * @default false
682     * @see https://giscus.app/
683     */
684    emitMetadata?: boolean;
685    /**
686     * The language setting of Giscus.
687     *
688     * Giscus 的语言设置。
689     *
690     * @default siteConfig.lang
691     */
692    lang?: string;
693    /**
694     * Whether to lazy load the comment area.
695     *
696     * 是否懒加载评论区
697     *
698     * @default true
699     */
700    lazyLoad?: boolean;
701  };
702  /**
703   * The configuration of Waline.
704   *
705   * Waline 的配置。
706   *
707   * @see https://waline.js.org/
708   */
709  waline?: {
710    /**
711     * The server URL of Waline.
712     *
713     * Waline 的服务端地址。
714     *
715     * @see https://waline.js.org/reference/client/props.html#serverurl
716     */
717    serverURL: string;
718    /**
719     * The path processor of the page.
720     * The parameter is `Astro.url.pathname`, and the return value will be passed to Waline as `path`.
721     *
722     * 页面路径处理器。传入参数为 `Astro.url.pathname`,返回值将传入 Waline 作为 `path`。
723     *
724     * @default (path) => path
725     * @see https://docs.astro.build/reference/api-reference/#url
726     * @see https://waline.js.org/reference/client/props.html#path
727     */
728    path?: (path: string) => string;
729    /**
730     * Reviewer attributes of Waline.
731     *
732     * Waline 的评论者相关属性。
733     *
734     * @default ['nick', 'mail', 'link']
735     * @see https://waline.js.org/reference/client/props.html#meta
736     */
737    meta?: ('nick' | 'mail' | 'link')[];
738    /**
739     * Required reviewer attributes of Waline.
740     *
741     * Waline 的评论者必填属性。
742     *
743     * @default []
744     * @see https://waline.js.org/reference/client/props.html#requiredmeta
745     */
746    requiredMeta?: [] | ['nick'] | ['nick', 'mail'];
747    /**
748     * Whether to enable or force to login.
749     *
750     * 是否启用或强制登录。
751     *
752     * @default 'enable'
753     * @see https://waline.js.org/reference/client/props.html#login
754     */
755    login?: 'enable' | 'disable' | 'force';
756    /**
757     * The word limit of the comment.
758     *
759     * 评论的字数限制。
760     *
761     * @default 500
762     * @see https://waline.js.org/reference/client/props.html#wordlimit
763     */
764    wordLimit?: number;
765    /**
766     * The page size of the comments.
767     *
768     * 评论的分页大小。
769     *
770     * @default 10
771     * @see https://waline.js.org/reference/client/props.html#pagesize
772     */
773    pageSize?: number;
774    /**
775     * Whether to enable reactions.
776     *
777     * 是否启用表情。
778     *
779     * @default false
780     * @see https://waline.js.org/reference/client/props.html#reaction
781     */
782    reaction?: boolean | string[];
783  };
784  /**
785   * The configuration of Artalk.
786   * Most settings should be configured on the server side,
787   * so only the most basic configuration is provided here.
788   *
789   * Artalk 的配置。大多数设置应当在服务端进行配置,因此这里仅提供最基本的配置。
790   *
791   * @see https://artalk.js.org/
792   */
793  artalk?: {
794    /**
795     * The server URL of Artalk.
796     *
797     * Artalk 的服务端地址。
798     *
799     * @see https://artalk.js.org/en/guide/frontend/config.html#server
800     */
801    serverURL: string;
802    /**
803     * Language setting of Artalk.
804     *
805     * 语言设置
806     *
807     * @default siteConfig.lang
808     * @see https://artalk.js.org/en/guide/frontend/config.html#locale
809     */
810    locale?: string;
811  };
812};