chore: cleanup
This commit is contained in:
@@ -68,6 +68,80 @@ const TAG = {
|
|||||||
tr: "tr",
|
tr: "tr",
|
||||||
} satisfies Record<Locale, string>
|
} satisfies Record<Locale, string>
|
||||||
|
|
||||||
|
const DOCS = {
|
||||||
|
en: "root",
|
||||||
|
zh: "zh-cn",
|
||||||
|
zht: "zh-tw",
|
||||||
|
ko: "ko",
|
||||||
|
de: "de",
|
||||||
|
es: "es",
|
||||||
|
fr: "fr",
|
||||||
|
it: "it",
|
||||||
|
da: "da",
|
||||||
|
ja: "ja",
|
||||||
|
pl: "pl",
|
||||||
|
ru: "ru",
|
||||||
|
ar: "ar",
|
||||||
|
no: "nb",
|
||||||
|
br: "pt-br",
|
||||||
|
th: "th",
|
||||||
|
tr: "tr",
|
||||||
|
} satisfies Record<Locale, string>
|
||||||
|
|
||||||
|
const DOCS_SEGMENT = new Set([
|
||||||
|
"ar",
|
||||||
|
"bs",
|
||||||
|
"da",
|
||||||
|
"de",
|
||||||
|
"es",
|
||||||
|
"fr",
|
||||||
|
"it",
|
||||||
|
"ja",
|
||||||
|
"ko",
|
||||||
|
"nb",
|
||||||
|
"pl",
|
||||||
|
"pt-br",
|
||||||
|
"ru",
|
||||||
|
"th",
|
||||||
|
"tr",
|
||||||
|
"zh-cn",
|
||||||
|
"zh-tw",
|
||||||
|
])
|
||||||
|
|
||||||
|
function suffix(pathname: string) {
|
||||||
|
const index = pathname.search(/[?#]/)
|
||||||
|
if (index === -1) {
|
||||||
|
return {
|
||||||
|
path: fix(pathname),
|
||||||
|
suffix: "",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
path: fix(pathname.slice(0, index)),
|
||||||
|
suffix: pathname.slice(index),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function docs(locale: Locale, pathname: string) {
|
||||||
|
const value = DOCS[locale]
|
||||||
|
const next = suffix(pathname)
|
||||||
|
if (next.path !== "/docs" && next.path !== "/docs/" && !next.path.startsWith("/docs/")) {
|
||||||
|
return `${next.path}${next.suffix}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value === "root") return `${next.path}${next.suffix}`
|
||||||
|
|
||||||
|
const hit = /^\/docs\/([^/]+)(\/.*)?$/.exec(next.path)
|
||||||
|
if (hit && DOCS_SEGMENT.has(hit[1] ?? "")) {
|
||||||
|
return `${next.path}${next.suffix}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next.path === "/docs") return `/docs/${value}${next.suffix}`
|
||||||
|
if (next.path === "/docs/") return `/docs/${value}/${next.suffix}`
|
||||||
|
return `/docs/${value}${next.path.slice("/docs".length)}${next.suffix}`
|
||||||
|
}
|
||||||
|
|
||||||
export function parseLocale(value: unknown): Locale | null {
|
export function parseLocale(value: unknown): Locale | null {
|
||||||
if (typeof value !== "string") return null
|
if (typeof value !== "string") return null
|
||||||
if ((LOCALES as readonly string[]).includes(value)) return value as Locale
|
if ((LOCALES as readonly string[]).includes(value)) return value as Locale
|
||||||
@@ -90,7 +164,7 @@ export function strip(pathname: string) {
|
|||||||
|
|
||||||
export function route(locale: Locale, pathname: string) {
|
export function route(locale: Locale, pathname: string) {
|
||||||
const next = strip(pathname)
|
const next = strip(pathname)
|
||||||
if (next.startsWith("/docs")) return next
|
if (next.startsWith("/docs")) return docs(locale, next)
|
||||||
if (next.startsWith("/auth")) return next
|
if (next.startsWith("/auth")) return next
|
||||||
if (next.startsWith("/workspace")) return next
|
if (next.startsWith("/workspace")) return next
|
||||||
if (locale === "en") return next
|
if (locale === "en") return next
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import type { APIEvent } from "@solidjs/start/server"
|
import type { APIEvent } from "@solidjs/start/server"
|
||||||
import { localeFromRequest, tag } from "~/lib/language"
|
import { docs, localeFromRequest, tag } from "~/lib/language"
|
||||||
|
|
||||||
async function handler(evt: APIEvent) {
|
async function handler(evt: APIEvent) {
|
||||||
const req = evt.request.clone()
|
const req = evt.request.clone()
|
||||||
const url = new URL(req.url)
|
const url = new URL(req.url)
|
||||||
const targetUrl = `https://docs.opencode.ai${url.pathname}${url.search}`
|
const locale = localeFromRequest(req)
|
||||||
|
const targetUrl = `https://docs.opencode.ai${docs(locale, url.pathname)}${url.search}`
|
||||||
|
|
||||||
const headers = new Headers(req.headers)
|
const headers = new Headers(req.headers)
|
||||||
headers.set("accept-language", tag(localeFromRequest(req)))
|
headers.set("accept-language", tag(locale))
|
||||||
|
|
||||||
const response = await fetch(targetUrl, {
|
const response = await fetch(targetUrl, {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import type { APIEvent } from "@solidjs/start/server"
|
import type { APIEvent } from "@solidjs/start/server"
|
||||||
import { localeFromRequest, tag } from "~/lib/language"
|
import { docs, localeFromRequest, tag } from "~/lib/language"
|
||||||
|
|
||||||
async function handler(evt: APIEvent) {
|
async function handler(evt: APIEvent) {
|
||||||
const req = evt.request.clone()
|
const req = evt.request.clone()
|
||||||
const url = new URL(req.url)
|
const url = new URL(req.url)
|
||||||
const targetUrl = `https://docs.opencode.ai${url.pathname}${url.search}`
|
const locale = localeFromRequest(req)
|
||||||
|
const targetUrl = `https://docs.opencode.ai${docs(locale, url.pathname)}${url.search}`
|
||||||
|
|
||||||
const headers = new Headers(req.headers)
|
const headers = new Headers(req.headers)
|
||||||
headers.set("accept-language", tag(localeFromRequest(req)))
|
headers.set("accept-language", tag(locale))
|
||||||
|
|
||||||
const response = await fetch(targetUrl, {
|
const response = await fetch(targetUrl, {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ export default function Download() {
|
|||||||
</span>
|
</span>
|
||||||
<span>VS Code</span>
|
<span>VS Code</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="/docs/ide/" data-component="action-button">
|
<a href={language.route("/docs/ide/")} data-component="action-button">
|
||||||
{i18n.t("download.action.install")}
|
{i18n.t("download.action.install")}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -318,7 +318,7 @@ export default function Download() {
|
|||||||
</span>
|
</span>
|
||||||
<span>Cursor</span>
|
<span>Cursor</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="/docs/ide/" data-component="action-button">
|
<a href={language.route("/docs/ide/")} data-component="action-button">
|
||||||
{i18n.t("download.action.install")}
|
{i18n.t("download.action.install")}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -335,7 +335,7 @@ export default function Download() {
|
|||||||
</span>
|
</span>
|
||||||
<span>Zed</span>
|
<span>Zed</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="/docs/ide/" data-component="action-button">
|
<a href={language.route("/docs/ide/")} data-component="action-button">
|
||||||
{i18n.t("download.action.install")}
|
{i18n.t("download.action.install")}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -352,7 +352,7 @@ export default function Download() {
|
|||||||
</span>
|
</span>
|
||||||
<span>Windsurf</span>
|
<span>Windsurf</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="/docs/ide/" data-component="action-button">
|
<a href={language.route("/docs/ide/")} data-component="action-button">
|
||||||
{i18n.t("download.action.install")}
|
{i18n.t("download.action.install")}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -369,7 +369,7 @@ export default function Download() {
|
|||||||
</span>
|
</span>
|
||||||
<span>VSCodium</span>
|
<span>VSCodium</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="/docs/ide/" data-component="action-button">
|
<a href={language.route("/docs/ide/")} data-component="action-button">
|
||||||
{i18n.t("download.action.install")}
|
{i18n.t("download.action.install")}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -393,7 +393,7 @@ export default function Download() {
|
|||||||
</span>
|
</span>
|
||||||
<span>GitHub</span>
|
<span>GitHub</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="/docs/github/" data-component="action-button">
|
<a href={language.route("/docs/github/")} data-component="action-button">
|
||||||
{i18n.t("download.action.install")}
|
{i18n.t("download.action.install")}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -410,7 +410,7 @@ export default function Download() {
|
|||||||
</span>
|
</span>
|
||||||
<span>GitLab</span>
|
<span>GitLab</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="/docs/gitlab/" data-component="action-button">
|
<a href={language.route("/docs/gitlab/")} data-component="action-button">
|
||||||
{i18n.t("download.action.install")}
|
{i18n.t("download.action.install")}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import type { APIEvent } from "@solidjs/start/server"
|
import type { APIEvent } from "@solidjs/start/server"
|
||||||
import { localeFromRequest, tag } from "~/lib/language"
|
import { docs, localeFromRequest, tag } from "~/lib/language"
|
||||||
|
|
||||||
async function handler(evt: APIEvent) {
|
async function handler(evt: APIEvent) {
|
||||||
const req = evt.request.clone()
|
const req = evt.request.clone()
|
||||||
const url = new URL(req.url)
|
const url = new URL(req.url)
|
||||||
const targetUrl = `https://docs.opencode.ai/docs${url.pathname}${url.search}`
|
const locale = localeFromRequest(req)
|
||||||
|
const targetUrl = `https://docs.opencode.ai${docs(locale, `/docs${url.pathname}`)}${url.search}`
|
||||||
|
|
||||||
const headers = new Headers(req.headers)
|
const headers = new Headers(req.headers)
|
||||||
headers.set("accept-language", tag(localeFromRequest(req)))
|
headers.set("accept-language", tag(locale))
|
||||||
|
|
||||||
const response = await fetch(targetUrl, {
|
const response = await fetch(targetUrl, {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
|
|||||||
@@ -9,10 +9,12 @@ import { GraphSection } from "./graph-section"
|
|||||||
import { IconLogo } from "~/component/icon"
|
import { IconLogo } from "~/component/icon"
|
||||||
import { querySessionInfo, queryBillingInfo, createCheckoutUrl, formatBalance } from "../common"
|
import { querySessionInfo, queryBillingInfo, createCheckoutUrl, formatBalance } from "../common"
|
||||||
import { useI18n } from "~/context/i18n"
|
import { useI18n } from "~/context/i18n"
|
||||||
|
import { useLanguage } from "~/context/language"
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
const params = useParams()
|
const params = useParams()
|
||||||
const i18n = useI18n()
|
const i18n = useI18n()
|
||||||
|
const language = useLanguage()
|
||||||
const userInfo = createAsync(() => querySessionInfo(params.id!))
|
const userInfo = createAsync(() => querySessionInfo(params.id!))
|
||||||
const billingInfo = createAsync(() => queryBillingInfo(params.id!))
|
const billingInfo = createAsync(() => queryBillingInfo(params.id!))
|
||||||
const checkoutAction = useAction(createCheckoutUrl)
|
const checkoutAction = useAction(createCheckoutUrl)
|
||||||
@@ -38,7 +40,7 @@ export default function () {
|
|||||||
<p>
|
<p>
|
||||||
<span>
|
<span>
|
||||||
{i18n.t("workspace.home.banner.beforeLink")}{" "}
|
{i18n.t("workspace.home.banner.beforeLink")}{" "}
|
||||||
<a target="_blank" href="/docs/zen">
|
<a target="_blank" href={language.route("/docs/zen")}>
|
||||||
{i18n.t("common.learnMore")}
|
{i18n.t("common.learnMore")}
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
|
|||||||
Reference in New Issue
Block a user