Skip to content

Commit 537baad

Browse files
committed
client redirects
1 parent 5f5b6f9 commit 537baad

File tree

6 files changed

+187
-2
lines changed

6 files changed

+187
-2
lines changed

site/docusaurus.config.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { themes as prismThemes } from 'prism-react-renderer';
22
import type { Config } from '@docusaurus/types';
33
import type * as Preset from '@docusaurus/preset-classic';
4+
import { redirects as redirectList, createRedirects } from './redirects';
45

56
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
67

@@ -102,6 +103,16 @@ const config: Config = {
102103
],
103104
],
104105

106+
plugins: [
107+
[
108+
'@docusaurus/plugin-client-redirects',
109+
{
110+
redirects: redirectList,
111+
createRedirects,
112+
},
113+
],
114+
],
115+
105116
themes: [
106117
[
107118
require.resolve('@easyops-cn/docusaurus-search-local'),

site/package-lock.json

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
},
1717
"dependencies": {
1818
"@docusaurus/core": "^3.8.1",
19+
"@docusaurus/plugin-client-redirects": "^3.8.1",
1920
"@docusaurus/preset-classic": "^3.8.1",
2021
"@docusaurus/remark-plugin-npm2yarn": "^3.8.1",
2122
"@docusaurus/theme-mermaid": "^3.8.1",

site/redirects.ts

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// Redirect configuration for Docusaurus client-side redirects
2+
// Based on GitBook .gitbook.yaml redirects
3+
4+
type RedirectRule = {
5+
to: string;
6+
from: string | string[];
7+
};
8+
9+
export const redirects: RedirectRule[] = [
10+
// Operations API
11+
{ from: '/developers/operations-api/utilities', to: '/developers/operations-api/system-operations' },
12+
13+
// Installation paths
14+
{ from: '/install-harperdb', to: '/deployments/install-harper/' },
15+
{ from: '/install-harperdb/linux', to: '/deployments/install-harper/linux' },
16+
{ from: '/install-harperdb/other', to: '/deployments/install-harper/' },
17+
{ from: '/install-harperdb/docker', to: '/deployments/install-harper/' },
18+
{ from: '/install-harperdb/mac', to: '/deployments/install-harper/' },
19+
{ from: '/install-harperdb/windows', to: '/deployments/install-harper/' },
20+
{ from: '/install-harperdb/linux-quickstart', to: '/deployments/install-harper/linux' },
21+
{ from: '/install-harperdb/offline', to: '/deployments/install-harper/' },
22+
{ from: '/install-harperdb/node-ver-requirement', to: '/deployments/install-harper/' },
23+
{ from: '/deployments/install-harperdb', to: '/deployments/install-harper/' },
24+
{ from: '/deployments/install-harperdb/linux', to: '/deployments/install-harper/linux' },
25+
26+
// Harper Studio (old HarperDB Studio paths)
27+
{ from: '/harperdb-studio', to: '/administration/harper-studio/' },
28+
{ from: '/harperdb-studio/create-account', to: '/administration/harper-studio/create-account' },
29+
{ from: '/harperdb-studio/login-password-reset', to: '/administration/harper-studio/login-password-reset' },
30+
{ from: ['/harperdb-studio/resources', '/administration/harper-studio/resources'], to: '/administration/harper-studio/' },
31+
{ from: '/harperdb-studio/organizations', to: '/administration/harper-studio/organizations' },
32+
{ from: '/harperdb-studio/instances', to: '/administration/harper-studio/instances' },
33+
{ from: '/harperdb-studio/query-instance-data', to: '/administration/harper-studio/query-instance-data' },
34+
{ from: '/harperdb-studio/manage-schemas-browse-data', to: '/administration/harper-studio/manage-databases-browse-data' },
35+
{ from: ['/harperdb-studio/manage-charts', '/administration/harper-studio/manage-charts'], to: '/administration/harper-studio/query-instance-data' },
36+
{ from: '/harperdb-studio/manage-clustering', to: '/administration/harper-studio/manage-replication' },
37+
{ from: '/harperdb-studio/manage-instance-users', to: '/administration/harper-studio/manage-instance-users' },
38+
{ from: '/harperdb-studio/manage-instance-roles', to: '/administration/harper-studio/manage-instance-users' },
39+
{ from: '/harperdb-studio/manage-functions', to: '/administration/harper-studio/manage-applications' },
40+
{ from: '/harperdb-studio/instance-metrics', to: '/administration/harper-studio/instance-metrics' },
41+
{ from: '/harperdb-studio/instance-configuration', to: '/administration/harper-studio/instance-configuration' },
42+
{ from: '/harperdb-studio/enable-mixed-content', to: '/administration/harper-studio/enable-mixed-content' },
43+
44+
// Harper Cloud (old HarperDB Cloud paths)
45+
{ from: '/harperdb-cloud', to: '/deployments/harper-cloud/' },
46+
47+
// Security
48+
{ from: '/security', to: '/developers/security/' },
49+
{ from: '/security/jwt-auth', to: '/developers/security/jwt-auth' },
50+
{ from: '/security/basic-auth', to: '/developers/security/basic-auth' },
51+
{ from: '/security/configuration', to: '/developers/security/configuration' },
52+
{ from: '/security/users-and-roles', to: '/developers/security/users-and-roles' },
53+
54+
// Custom Functions → Applications
55+
{ from: '/custom-functions', to: '/developers/applications/' },
56+
{ from: '/custom-functions/define-routes', to: '/developers/applications/define-routes' },
57+
{ from: ['/custom-functions/using-npm-git', '/developers/custom-functions/create-project'], to: '/developers/applications/' },
58+
{ from: '/custom-functions/custom-functions-operations', to: '/developers/operations-api/' },
59+
{ from: '/custom-functions/debugging-custom-function', to: '/developers/applications/debugging' },
60+
{ from: '/custom-functions/example-projects', to: '/developers/applications/example-projects' },
61+
62+
// Add-ons and SDKs
63+
{ from: '/add-ons-and-sdks', to: '/developers/applications/' },
64+
{ from: '/add-ons-and-sdks/google-data-studio', to: '/developers/miscellaneous/google-data-studio' },
65+
66+
// SQL Guide
67+
{ from: '/sql-guide', to: '/developers/sql-guide/' },
68+
69+
// CLI
70+
{ from: '/harperdb-cli', to: '/deployments/harper-cli' },
71+
{ from: '/deployments/harperdb-cli', to: '/deployments/harper-cli' },
72+
73+
// Top-level paths
74+
{ from: '/configuration', to: '/deployments/configuration' },
75+
{ from: '/logging', to: '/administration/logging/standard-logging' },
76+
{ from: '/transaction-logging', to: '/administration/logging/transaction-logging' },
77+
{ from: '/audit-logging', to: '/administration/logging/audit-logging' },
78+
{ from: '/jobs', to: '/administration/jobs' },
79+
{ from: '/upgrade-hdb-instance', to: '/deployments/upgrade-hdb-instance' },
80+
{ from: '/reference', to: '/technical-details/reference/' },
81+
{ from: '/operations-api', to: '/developers/operations-api/' },
82+
{ from: '/rest', to: '/developers/rest' },
83+
{ from: '/api', to: '/developers/operations-api/' },
84+
85+
// File rename redirect
86+
{ from: '/administration/logging/logging', to: '/administration/logging/standard-logging' },
87+
];
88+
89+
// Function to create wildcard redirects for moved sections
90+
export function createRedirects(existingPath: string): string[] | undefined {
91+
const redirects: string[] = [];
92+
93+
// Handle wildcard redirects for paths with subpaths
94+
if (existingPath.startsWith('/administration/harper-studio/')) {
95+
const subpath = existingPath.replace('/administration/harper-studio/', '');
96+
if (subpath) { // Only add redirect if there's an actual subpath
97+
redirects.push(`/administration/harperdb-studio/${subpath}`);
98+
}
99+
}
100+
101+
if (existingPath.startsWith('/deployments/harper-cloud/')) {
102+
const subpath = existingPath.replace('/deployments/harper-cloud/', '');
103+
if (subpath) { // Only add redirect if there's an actual subpath
104+
redirects.push(`/harperdb-cloud/${subpath}`);
105+
redirects.push(`/deployments/harperdb-cloud/${subpath}`);
106+
}
107+
}
108+
109+
if (existingPath.startsWith('/developers/clustering/')) {
110+
const subpath = existingPath.replace('/developers/clustering/', '');
111+
if (subpath) { // Only add redirect if there's an actual subpath
112+
redirects.push(`/clustering/${subpath}`);
113+
}
114+
}
115+
116+
if (existingPath.startsWith('/developers/sql-guide/')) {
117+
const subpath = existingPath.replace('/developers/sql-guide/', '');
118+
if (subpath) { // Only add redirect if there's an actual subpath
119+
redirects.push(`/sql-guide/${subpath}`);
120+
}
121+
}
122+
123+
return redirects.length > 0 ? redirects : undefined;
124+
}

site/scripts/convert-gitbook-to-docusaurus.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,12 @@ function processDirectory(dirPath, targetDirPath, docsDir = dirPath, outputDir =
17481748
: null;
17491749

17501750
if (entry.isDirectory()) {
1751+
// Skip custom-functions directory for versions 4.2+ (doesn't exist in live docs, use redirects)
1752+
// But keep it for version 4.1 which needs it for its sidebar
1753+
if (entry.name === 'custom-functions' && options?.version && options.version !== '4.1') {
1754+
console.log(` Skipping custom-functions directory for version ${options.version} (will use redirects instead)`);
1755+
continue;
1756+
}
17511757
processDirectory(actualSourcePath, targetPath, docsDir, outputDir, options);
17521758
} else if (entry.isFile() && entry.name.endsWith('.md')) {
17531759
convertFile(actualSourcePath, targetPath, docsDir, outputDir, options);

site/scripts/migrate-branches-to-versions.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@ const RELEASE_BRANCHES = [
3131
// Map branch names to version numbers
3232
// Version-specific exclusions - paths that shouldn't be migrated
3333
const VERSION_EXCLUSIONS = {
34+
// '4.1': [], // Version 4.1 needs custom-functions for its sidebar structure
35+
'4.2': ['custom-functions'], // Custom functions deprecated, use redirects instead
3436
'4.3': ['custom-functions'], // Not in SUMMARY.md, not part of actual docs
35-
'4.5': ['getting-started.md'], // Root-level file not in SUMMARY.md for 4.5, causes broken links
37+
'4.4': ['custom-functions'], // Custom functions deprecated, use redirects instead
38+
'4.5': ['getting-started.md', 'custom-functions'], // Root-level file not in SUMMARY.md for 4.5, custom functions deprecated
39+
'4.6': ['custom-functions'], // Custom functions deprecated, use redirects instead
3640
// Add more version-specific exclusions as needed
37-
// '4.4': ['some-other-folder'],
3841
};
3942

4043
function branchToVersion(branch) {
@@ -222,6 +225,21 @@ function processBranch(branch, isLatest = false) {
222225
delete process.env.IMAGES_PATH;
223226
}
224227

228+
// Fix version-specific broken links
229+
if (version !== '4.1') {
230+
// Fix the link to custom-functions/define-helpers in define-routes.md
231+
const defineRoutesPath = path.join(outputPath, 'developers', 'applications', 'define-routes.md');
232+
if (fs.existsSync(defineRoutesPath)) {
233+
console.log(`Fixing broken link in define-routes.md for version ${version}...`);
234+
let content = fs.readFileSync(defineRoutesPath, 'utf8');
235+
content = content.replace(
236+
'[Define Helpers](../../custom-functions/define-helpers)',
237+
'[Helper Methods](#helper-methods)'
238+
);
239+
fs.writeFileSync(defineRoutesPath, content);
240+
}
241+
}
242+
225243
// Always create versioned docs
226244
const versionedPath = path.join(VERSIONED_DOCS_DIR, `version-${version}`);
227245
console.log(`Creating versioned docs at ${versionedPath}...`);

0 commit comments

Comments
 (0)