feat(website): escape url parts

This commit is contained in:
daimond113 2025-01-10 14:07:52 +01:00
parent dcc869c025
commit a39b1bb60a
No known key found for this signature in database
GPG key ID: 3A8ECE51328B513C
17 changed files with 32 additions and 30 deletions

View file

@ -23,7 +23,7 @@ the following content:
api = "https://registry.acme.local/"
# package download URL (optional)
download = "{API_URL}/v0/packages/{PACKAGE}/{PACKAGE_VERSION}/{PACKAGE_TARGET}"
download = "{API_URL}/v0/packages/{PACKAGE}/{PACKAGE_VERSION}/{PACKAGE_TARGET}/archive"
# the client ID of the GitHub OAuth app (optional)
github_oauth_client_id = "a1d648966fdfbdcd9295"
@ -58,7 +58,7 @@ scripts_packages = ["pesde/scripts_rojo"]
- `{PACKAGE_VERSION}`: The package version.
- `{PACKAGE_TARGET}`: The package target.
Defaults to `{API_URL}/v0/packages/{PACKAGE}/{PACKAGE_VERSION}/{PACKAGE_TARGET}`.
Defaults to `{API_URL}/v0/packages/{PACKAGE}/{PACKAGE_VERSION}/{PACKAGE_TARGET}/archive`.
- **github_oauth_client_id**: This is required if you use GitHub OAuth for
authentication. See below for more information.

View file

@ -1,6 +1,6 @@
use gix::Url;
use relative_path::RelativePathBuf;
use reqwest::header::{ACCEPT, AUTHORIZATION};
use reqwest::header::AUTHORIZATION;
use serde::{Deserialize, Serialize};
use std::{
collections::{BTreeMap, BTreeSet, HashSet},
@ -220,7 +220,7 @@ impl PackageSource for PesdePackageSource {
&urlencoding::encode(&id.version_id().target().to_string()),
);
let mut request = reqwest.get(&url).header(ACCEPT, "application/octet-stream");
let mut request = reqwest.get(&url);
if let Some(token) = project.auth_config().tokens().get(&self.repo_url) {
tracing::debug!("using token for {}", self.repo_url);
@ -412,7 +412,7 @@ impl IndexConfig {
pub fn download(&self) -> String {
self.download
.as_deref()
.unwrap_or("{API_URL}/v0/packages/{PACKAGE}/{PACKAGE_VERSION}/{PACKAGE_TARGET}")
.unwrap_or("{API_URL}/v0/packages/{PACKAGE}/{PACKAGE_VERSION}/{PACKAGE_TARGET}/archive")
.replace("{API_URL}", self.api())
}
}

View file

@ -18,7 +18,7 @@ const fetchPackage = async (fetcher: typeof fetch, options: FetchPackageOptions)
try {
return await fetchRegistryJson<PackageVersionResponse>(
`packages/${encodeURIComponent(`${scope}/${name}`)}/${version}/${target}`,
`packages/${encodeURIComponent(`${scope}/${name}`)}/${encodeURIComponent(version)}/${encodeURIComponent(target)}`,
fetcher,
)
} catch (e) {

View file

@ -11,7 +11,7 @@
const basePath = $derived.by(() => {
const { scope, name } = $page.params
return `/packages/${scope}/${name}`
return `/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`
})
const activeTab = $derived(

View file

@ -13,9 +13,9 @@
const { scope, name } = $page.params
if ("target" in $page.params) {
const { version } = $page.params
return `/packages/${scope}/${name}/${version}`
return `/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}/${encodeURIComponent(version)}`
}
return `/packages/${scope}/${name}/latest`
return `/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}/latest`
})
const items = ($page.data.pkg.targets as TargetInfo[]).map((target) => {

View file

@ -54,13 +54,16 @@ export const load: LayoutLoad = async ({ params, url, fetch }) => {
if (version === undefined || version === "latest" || !isTargetKind(target)) {
const pkg = await fetchRegistryJson<PackageVersionResponse>(
`packages/${encodeURIComponent(`${scope}/${name}`)}/${version ?? "latest"}/${target ?? "any"}`,
`packages/${encodeURIComponent(`${scope}/${name}`)}/${encodeURIComponent(version ?? "latest")}/${encodeURIComponent(target ?? "any")}`,
fetch,
)
const path = url.pathname.split("/").slice(6).join("/")
const path = url.pathname.split("/").slice(6).map(encodeURIComponent).join("/")
return redirect(303, `/packages/${scope}/${name}/${pkg.version}/${pkg.targets[0].kind}/${path}`)
return redirect(
303,
`/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}/${encodeURIComponent(pkg.version)}/${encodeURIComponent(pkg.targets[0].kind)}/${path}`,
)
}
const { pkg, versions } = await fetchPackageAndVersions(fetch, { scope, name, version, target })

View file

@ -13,6 +13,7 @@
import Toc from "./Toc.svelte"
import TocObserver from "./TocObserver.svelte"
import VersionSelector from "./VersionSelector.svelte"
import { TARGET_KIND_DISPLAY_NAMES, type TargetInfo, type TargetKind } from "$lib/registry-api"
const { children, data } = $props()
const [scope, name] = data.pkg.name.split("/")
@ -84,7 +85,7 @@
<span class="flex min-w-0 items-center">
<a
class="flex min-w-0 items-center"
href={`/packages/${scope}/${name}/${$page.params.version ?? "latest"}/${$page.params.target ?? "any"}`}
href={`/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}/${encodeURIComponent($page.params.version ?? "latest")}/${encodeURIComponent($page.params.target ?? "any")}`}
>
<span class="text-primary mr-2">
<Logomark class="h-7" />
@ -98,6 +99,9 @@
<button
{...props}
class="flex items-center transition-opacity data-[disabled]:opacity-50"
class:line-through={(
Object.entries($page.data.pkg.targets) as [TargetKind, TargetInfo][]
).find(([name]) => TARGET_KIND_DISPLAY_NAMES[name] === label)?.[1]?.yanked}
>
{label}
<ChevronsUpDown class="ml-1 size-4" />

View file

@ -41,7 +41,7 @@
>
<a
class="flex items-center truncate"
href={`/packages/${scope}/${name}/${$page.params.version ?? "latest"}/${$page.params.target ?? "any"}`}
href={`/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}/${encodeURIComponent($page.params.version ?? "latest")}/${encodeURIComponent($page.params.target ?? "any")}`}
>
{#snippet separator()}
<span class="text-body/60 px-2 text-xl">/</span>

View file

@ -12,7 +12,7 @@
const basePath = $derived.by(() => {
const { scope, name, version, target } = $page.params
return `/packages/${scope}/${name}/${version ?? "latest"}/${target ?? "any"}`
return `/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}/${encodeURIComponent(version ?? "latest")}/${encodeURIComponent(target ?? "any")}`
})
const href = $derived(`${basePath}/${tab}`)

View file

@ -18,7 +18,7 @@
const basePath = $derived.by(() => {
const { scope, name } = $page.params
return `/packages/${scope}/${name}`
return `/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`
})
</script>

View file

@ -18,7 +18,7 @@
const basePath = $derived.by(() => {
const { scope, name } = $page.params
return `/packages/${scope}/${name}`
return `/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}`
})
</script>
@ -32,7 +32,7 @@
const path = $page.data.activeTab === "docs" ? "docs/intro" : "reference"
fetchRegistryJson<PackageVersionResponse>(
`packages/${encodeURIComponent($page.data.pkg.name)}/${version}/any`,
`packages/${encodeURIComponent($page.data.pkg.name)}/${encodeURIComponent(version)}/any`,
fetch,
)
.then((pkg) => goto(`${basePath}/${version}/${pkg.targets[0].kind}/${path}`))

View file

@ -6,7 +6,7 @@ export const load: LayoutLoad = async ({ params, parent }) => {
const parentData = await parent()
const { scope, name, version, target } = params
const basePath = `/packages/${scope}/${name}/${version ?? "latest"}/${target ?? "any"}`
const basePath = `/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}/${encodeURIComponent(version ?? "latest")}/${encodeURIComponent(target ?? "any")}`
function docEntryToSidebarItem(entry: DocEntry): SidebarItem {
if ("name" in entry) {

View file

@ -18,7 +18,7 @@ const findDocTitle = (docs: DocEntry[], name: string): string | undefined => {
export const load: PageLoad = async ({ params, parent, fetch }) => {
try {
const page = await fetchRegistry(
`packages/${encodeURIComponent(`${params.scope}/${params.name}`)}/${params.version ?? "latest"}/${params.target ?? "any"}?doc=${encodeURIComponent(params.doc)}`,
`packages/${encodeURIComponent(`${params.scope}/${params.name}`)}/${encodeURIComponent(params.version ?? "latest")}/${encodeURIComponent(params.target ?? "any")}?doc=${encodeURIComponent(params.doc)}`,
fetch,
).then((r) => r.text())
@ -26,7 +26,7 @@ export const load: PageLoad = async ({ params, parent, fetch }) => {
path: `/docs/${params.doc}`,
value: page,
data: {
basePath: `/packages/${params.scope}/${params.name}/${params.version ?? "latest"}/${params.target ?? "any"}`,
basePath: `/packages/${encodeURIComponent(params.scope)}/${encodeURIComponent(params.name)}/${encodeURIComponent(params.version ?? "latest")}/${encodeURIComponent(params.target ?? "any")}`,
},
})

View file

@ -2,7 +2,7 @@ import type { LayoutLoad } from "./$types"
export const load: LayoutLoad = async ({ params, parent }) => {
const { scope, name, version, target } = params
const basePath = `/packages/${scope}/${name}/${version ?? "latest"}/${target ?? "any"}`
const basePath = `/packages/${encodeURIComponent(scope)}/${encodeURIComponent(name)}/${encodeURIComponent(version ?? "latest")}/${encodeURIComponent(target ?? "any")}`
const parentData = await parent()
return {

View file

@ -10,13 +10,8 @@ const fetchReadme = async (
) => {
try {
const res = await fetchRegistry(
`packages/${encodeURIComponent(name)}/${version}/${target}`,
`packages/${encodeURIComponent(name)}/${encodeURIComponent(version)}/${encodeURIComponent(target)}/readme`,
fetcher,
{
headers: {
Accept: "text/plain",
},
},
)
return res.text()

View file

@ -55,7 +55,7 @@
? {
href: isWally
? `https://wally.run/package/${stripWally(dependencyInfo.wally)}`
: `/packages/${dependencyInfo.name}/latest/${target}`,
: `/packages/${dependencyInfo.name}/latest/${encodeURIComponent(target)}`,
}
: {}}
class="after:absolute after:inset-0 after:content-['']"

View file

@ -22,7 +22,7 @@
>
<h2 class="text-heading font-semibold">
<a
href={`/packages/${data.name}/${pkgVersion.version}/any`}
href={`/packages/${data.name}/${encodeURIComponent(pkgVersion.version)}/any`}
class="after:absolute after:inset-0 after:content-['']"
>
{pkgVersion.version}