Skip to content

Commit 0ed6c15

Browse files
committed
chore: switch to vitepress
1 parent b80edc5 commit 0ed6c15

204 files changed

Lines changed: 21516 additions & 47651 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc.js

Lines changed: 0 additions & 26 deletions
This file was deleted.

.github/workflows/test.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
branches: [master]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v6
15+
- uses: pnpm/action-setup@v5
16+
- name: Use Node.js
17+
uses: actions/setup-node@v6
18+
with:
19+
node-version: 22
20+
cache: 'pnpm'
21+
- run: pnpm install --frozen-lockfile
22+
- run: pnpm test

.gitignore

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,17 @@ pids
1313
*.seed
1414
*.pid.lock
1515

16-
# Directory for instrumented libs generated by jscoverage/JSCover
17-
lib-cov
18-
1916
# Coverage directory used by tools like istanbul
2017
coverage
2118

2219
# nyc test coverage
2320
.nyc_output
2421

25-
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26-
.grunt
27-
28-
# Bower dependency directory (https://bower.io/)
29-
bower_components
30-
31-
# node-waf configuration
32-
.lock-wscript
33-
34-
# Compiled binary addons (https://nodejs.org/api/addons.html)
35-
build/Release
36-
3722
# Dependency directories
3823
node_modules/
3924
jspm_packages/
4025

41-
# TypeScript v1 declaration files
26+
# TypeScript declaration files
4227
typings/
4328

4429
# Optional npm cache directory
@@ -59,32 +44,18 @@ typings/
5944
# dotenv environment variables file
6045
.env
6146

62-
# parcel-bundler cache (https://parceljs.org/)
63-
.cache
64-
65-
# next.js build output
66-
.next
67-
68-
# nuxt.js build output
69-
.nuxt
70-
71-
# Nuxt generate
47+
# vitepress build output
7248
dist
73-
74-
# vuepress build output
75-
.vuepress/dist
76-
77-
# Serverless directories
78-
.serverless
49+
.vitepress/cache
7950

8051
# IDE / Editor
8152
.idea
8253

83-
# Service worker
84-
sw.*
85-
8654
# macOS
8755
.DS_Store
8856

8957
# Vim swap files
9058
*.swp
59+
60+
# Service worker (if any)
61+
sw.*

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
18.18.1
1+
24.14.0

.oxfmtrc.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"$schema": "./node_modules/oxfmt/configuration_schema.json",
3+
"singleQuote": true,
4+
"printWidth": 120,
5+
"sortPackageJson": false,
6+
"sortImports": {
7+
"groups": [
8+
"builtin",
9+
"external",
10+
["internal", "parent", "sibling", "index"],
11+
"type-builtin",
12+
"type-external",
13+
["type-internal", "type-parent", "type-sibling", "type-index"]
14+
]
15+
},
16+
"ignorePatterns": [],
17+
"overrides": [
18+
{
19+
"files": ["generated/**"],
20+
"options": {
21+
"printWidth": 80
22+
}
23+
}
24+
]
25+
}

.oxlintrc.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"$schema": "./node_modules/oxlint/configuration_schema.json",
3+
"plugins": ["typescript", "unicorn", "vue"],
4+
"env": {
5+
"node": true,
6+
"browser": true
7+
},
8+
"categories": {
9+
"correctness": "error",
10+
"perf": "error",
11+
"suspicious": "error",
12+
"pedantic": "warn",
13+
"style": "warn",
14+
"nursery": "warn"
15+
},
16+
"globals": {
17+
"defineProps": "readonly",
18+
"defineEmits": "readonly"
19+
},
20+
"rules": {
21+
"id-length": "off",
22+
"init-declarations": "off",
23+
"max-depth": "off",
24+
"max-lines-per-function": "off",
25+
"max-params": "off",
26+
"max-statements": "off",
27+
"no-await-in-loop": "off",
28+
"no-duplicate-imports": ["error", { "allowSeparateTypeImports": true }],
29+
"no-magic-numbers": "off",
30+
"no-ternary": "off",
31+
"prefer-global-this": "off",
32+
"sort-imports": "off",
33+
"typescript/consistent-type-imports": ["error", { "prefer": "type-imports", "fixStyle": "separate-type-imports" }],
34+
"unicorn/filename-case": "off",
35+
"unicorn/no-null": "off",
36+
"unicorn/prefer-node-protocol": "error"
37+
}
38+
}

.prettierrc

Lines changed: 0 additions & 3 deletions
This file was deleted.

.vitepress/config.ts

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import { defineConfig } from 'vitepress';
2+
import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-icons';
3+
4+
import modulesData from '../generated/metadata/modules.json' with { type: 'json' };
5+
import joiInfo from '../generated/modules/joi/info.json' with { type: 'json' };
6+
import { formatVersion } from './utils.js';
7+
8+
const modulesItems = Object.keys(modulesData)
9+
.filter((name) => name !== 'joi')
10+
.map((name) => ({
11+
link: `/module/${name}/install`,
12+
text: name,
13+
}));
14+
15+
const getModuleSidebar = (moduleName: string) => {
16+
const moduleData = modulesData[moduleName as keyof typeof modulesData];
17+
return [
18+
{
19+
items: [{ link: '/module/', text: 'All Modules' }, ...modulesItems],
20+
text: 'Modules',
21+
},
22+
{
23+
items: [
24+
{ link: `/module/${moduleName}/install`, text: 'Installation' },
25+
{
26+
items: moduleData.versions.map((version) => ({
27+
link: `/module/${moduleName}/api/${formatVersion(version.name)}`,
28+
text: formatVersion(version.name),
29+
})),
30+
link: `/module/${moduleName}/api/${formatVersion(moduleData.versions[0].name)}`,
31+
text: 'API',
32+
},
33+
{ link: `/module/${moduleName}/changelog`, text: 'Changelog' },
34+
],
35+
text: moduleName,
36+
},
37+
];
38+
};
39+
40+
const moduleSidebars = Object.fromEntries(
41+
Object.keys(modulesData)
42+
.filter((name) => name !== 'joi')
43+
.map((name) => [`/module/${name}/`, getModuleSidebar(name)]),
44+
);
45+
46+
export default defineConfig({
47+
appearance: true,
48+
cleanUrls: true,
49+
description: 'The most powerful data validation library for JS',
50+
head: [['link', { href: '/favicon2.png', rel: 'icon' }]],
51+
markdown: {
52+
config(md) {
53+
md.use(groupIconMdPlugin);
54+
},
55+
lineNumbers: true,
56+
theme: {
57+
dark: 'vitesse-dark',
58+
light: 'vitesse-light',
59+
},
60+
},
61+
outDir: 'dist',
62+
srcDir: 'docs',
63+
themeConfig: {
64+
docFooter: {
65+
next: false,
66+
prev: false,
67+
},
68+
footer: {
69+
copyright: 'Copyright © 2012-present hapi.js team',
70+
message:
71+
'<a href="https://www.netlify.com" target="_blank"><img src="https://www.netlify.com/img/global/badges/netlify-dark.svg" alt="Deploys by Netlify" style="display: inline-block; vertical-align: middle; height: 20px; margin-left: 10px;" /></a>',
72+
},
73+
logo: '/img/joiTransparent.png',
74+
nav: [
75+
{ link: '/', text: 'Home' },
76+
{ activeMatch: '^/api/', link: `/api/${formatVersion(joiInfo.versionsArray[0])}`, text: 'API' },
77+
{
78+
activeMatch: '^/resources/',
79+
link: '/resources/changelog',
80+
text: 'Resources',
81+
},
82+
{ activeMatch: '^/module/', link: '/module/', text: 'Modules' },
83+
{ activeMatch: '^/policies/', link: '/policies/coc', text: 'Policies' },
84+
{ activeMatch: '^/tester/', link: '/tester/', text: 'Sandbox' },
85+
],
86+
outline: {
87+
label: 'On this page',
88+
level: 'deep',
89+
},
90+
sidebar: {
91+
'/api/': [
92+
{
93+
items: [
94+
{
95+
items: joiInfo.versionsArray.map((version) => ({
96+
link: `/api/${formatVersion(version)}`,
97+
text: formatVersion(version),
98+
})),
99+
link: `/api/${formatVersion(joiInfo.versionsArray[0])}`,
100+
text: 'API',
101+
},
102+
],
103+
text: 'joi',
104+
},
105+
],
106+
'/module/': [
107+
{
108+
items: [{ link: '/module/', text: 'All Modules' }, ...modulesItems],
109+
text: 'Modules',
110+
},
111+
],
112+
'/policies/': [
113+
{
114+
items: [
115+
{ link: '/policies/coc', text: 'Code of Conduct' },
116+
{ link: '/policies/contributing', text: 'Contributing' },
117+
{ link: '/policies/license', text: 'License' },
118+
{ link: '/policies/security', text: 'Security' },
119+
{ link: '/policies/styleguide', text: 'Style Guide' },
120+
{ link: '/policies/support', text: 'Support' },
121+
],
122+
text: 'Policies',
123+
},
124+
],
125+
'/resources/': [
126+
{
127+
items: [
128+
{ link: '/resources/changelog', text: 'Changelog' },
129+
{ link: '/resources/status', text: 'Module Status' },
130+
],
131+
text: 'Resources',
132+
},
133+
],
134+
'/tester/': [
135+
{
136+
items: joiInfo.versionsArray.map((version) => ({
137+
link: `/tester/${formatVersion(version)}`,
138+
text: formatVersion(version),
139+
})),
140+
text: 'Versions',
141+
},
142+
],
143+
...moduleSidebars,
144+
},
145+
socialLinks: [{ icon: 'github', link: 'https://github.com/hapijs/joi' }],
146+
},
147+
title: 'joi.dev',
148+
titleTemplate: 'joi.dev - :title',
149+
vite: {
150+
plugins: [groupIconVitePlugin()],
151+
},
152+
});

.vitepress/theme/index.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import DefaultTheme from 'vitepress/theme';
2+
import { h } from 'vue';
3+
4+
import './variables.css';
5+
import './main.css';
6+
import 'virtual:group-icons.css';
7+
import CarbonAds from '../../components/CarbonAds.vue';
8+
import ModuleIndex from '../../components/ModuleIndex.vue';
9+
import StatusContent from '../../components/StatusContent.vue';
10+
import TesterContent from '../../components/TesterContent.vue';
11+
import { getRedirectPath } from './redirect.js';
12+
13+
import type { Theme } from 'vitepress';
14+
15+
export default {
16+
Layout() {
17+
return h(DefaultTheme.Layout, null, {
18+
'sidebar-nav-after': () => h(CarbonAds),
19+
});
20+
},
21+
enhanceApp({ app, router }) {
22+
app.component('ModuleIndex', ModuleIndex);
23+
app.component('StatusContent', StatusContent);
24+
app.component('TesterContent', TesterContent);
25+
26+
if (typeof window !== 'undefined') {
27+
router.onBeforeRouteChange = (to) => {
28+
const target = getRedirectPath(to);
29+
if (target) {
30+
router.go(target);
31+
return false;
32+
}
33+
};
34+
35+
const initialTarget = getRedirectPath(window.location.pathname);
36+
if (initialTarget) {
37+
router.go(initialTarget);
38+
}
39+
}
40+
},
41+
extends: DefaultTheme,
42+
} satisfies Theme;

0 commit comments

Comments
 (0)