Skip to content

Commit adb5448

Browse files
committed
feat: convert relative paths to absolute
1 parent 920eff9 commit adb5448

File tree

7 files changed

+50
-9
lines changed

7 files changed

+50
-9
lines changed

src/components/assets.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@ import {
88
Text,
99
} from "@chakra-ui/react";
1010
import { LuDownload } from "react-icons/lu";
11-
import type { StacAsset } from "stac-ts";
11+
import type { StacAsset, StacItem } from "stac-ts";
12+
import { makeAbsoluteUrl } from "../http";
1213

1314
export default function Assets({
15+
item,
1416
assets,
1517
}: {
18+
item: StacItem;
1619
assets: { [k: string]: StacAsset };
1720
}) {
1821
return (
@@ -34,7 +37,7 @@ export default function Assets({
3437
<Card.Footer>
3538
<ButtonGroup size={"xs"} variant={"subtle"}>
3639
<IconButton asChild>
37-
<a href={asset.href} target="_blank">
40+
<a href={makeAbsoluteUrl(item, asset.href)} target="_blank">
3841
<LuDownload></LuDownload>
3942
</a>
4043
</IconButton>

src/components/catalog.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@ import { ChildCard } from "./children";
66
import { CollectionSearch } from "./search/collection";
77
import Section from "./section";
88
import Value from "./value";
9+
import { makeAbsoluteUrl } from "../http";
910

1011
export function Catalog({ catalog }: { catalog: StacCatalog }) {
1112
const { catalogs, collections } = useStacMap();
12-
const selfHref = catalog.links?.find((link) => link.rel === "self")?.href;
13+
const selfHref = makeAbsoluteUrl(
14+
catalog,
15+
catalog.links?.find((link) => link.rel === "self")?.href,
16+
);
1317
return (
1418
<Stack>
1519
<Value value={catalog}></Value>

src/components/children.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { ReactNode } from "react";
33
import { MarkdownHooks } from "react-markdown";
44
import type { StacCatalog, StacCollection } from "stac-ts";
55
import useStacMap from "../hooks/stac-map";
6+
import { makeAbsoluteUrl } from "../http";
67

78
export function Children({
89
heading,
@@ -27,7 +28,10 @@ export function ChildCard({
2728
footer?: ReactNode;
2829
}) {
2930
const { setHref } = useStacMap();
30-
const selfHref = child.links.find((link) => link.rel === "self")?.href;
31+
const selfHref = makeAbsoluteUrl(
32+
child,
33+
child.links.find((link) => link.rel === "self")?.href,
34+
);
3135

3236
return (
3337
<Card.Root size={"sm"}>

src/components/item.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default function Item({ item }: { item: StacItem }) {
1919
</HStack>
2020
}
2121
>
22-
<Assets assets={item.assets}></Assets>
22+
<Assets item={item} assets={item.assets}></Assets>
2323
</Section>
2424
</Stack>
2525
);

src/components/value.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { StacValue } from "../types/stac";
77
import Section from "./section";
88
import Thumbnail from "./thumbnail";
99
import { Prose } from "./ui/prose";
10+
import { makeAbsoluteUrl } from "../http";
1011

1112
export default function Value({
1213
value,
@@ -21,7 +22,11 @@ export default function Value({
2122
"thumbnail" in value.assets
2223
? (value.assets.thumbnail as StacAsset)
2324
: undefined;
24-
const selfHref = value.links?.find((link) => link.rel == "self")?.href;
25+
26+
const selfHref = makeAbsoluteUrl(
27+
value,
28+
value.links?.find((link) => link.rel == "self")?.href,
29+
);
2530

2631
return (
2732
<Section

src/hooks/stac-children-and-items.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useInfiniteQuery, useQueries } from "@tanstack/react-query";
22
import { useEffect } from "react";
33
import type { StacCatalog, StacCollection, StacItem } from "stac-ts";
4-
import { fetchStac, fetchStacLink } from "../http";
4+
import { fetchStac, fetchStacLink, makeAbsoluteUrl } from "../http";
55
import type { StacCollections, StacValue } from "../types/stac";
66

77
import { booleanValid } from "@turf/boolean-valid";
@@ -29,7 +29,10 @@ export default function useStacChildrenAndItems(
2929
}
3030

3131
function useStacCollections(value: StacValue | undefined) {
32-
const href = value?.links?.find((link) => link.rel == "data")?.href;
32+
const href = makeAbsoluteUrl(
33+
value,
34+
value?.links?.find((link) => link.rel == "data")?.href,
35+
);
3336
const { data, isFetching, hasNextPage, fetchNextPage } =
3437
useInfiniteQuery<StacCollections | null>({
3538
queryKey: ["collections", href],
@@ -67,7 +70,7 @@ function useStacLinks(value: StacValue | undefined, href: string | undefined) {
6770
.map((link) => {
6871
return {
6972
queryKey: ["link", link, href],
70-
queryFn: () => fetchStacLink(link, href),
73+
queryFn: () => fetchStacLink(link, makeAbsoluteUrl(value, href)),
7174
};
7275
}) || [],
7376
});

src/http.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import type { StacLink } from "stac-ts";
22
import type { StacValue } from "./types/stac";
33

4+
export const SourceKey = Symbol("source");
5+
type StacValueWithSource = StacValue & { [SourceKey]?: string };
6+
47
export async function fetchStac(
58
href: string | URL,
69
method: "GET" | "POST" = "GET",
@@ -34,6 +37,7 @@ export async function fetchStacLink(link: StacLink, href?: string | undefined) {
3437

3538
// eslint-disable-next-line
3639
function maybeAddSelfLink(value: any, href: string) {
40+
value[SourceKey] = href;
3741
if (!(value as StacValue)?.links?.find((link) => link.rel == "self")) {
3842
const link = { href, rel: "self" };
3943
if (Array.isArray(value.links)) {
@@ -44,3 +48,21 @@ function maybeAddSelfLink(value: any, href: string) {
4448
}
4549
return value;
4650
}
51+
52+
/**
53+
* Attempt to convert a possibly relative URL to an absolute URL
54+
* if the STAC document has been fetched via {@link fetchStac} or {@link fetchStacLink}
55+
*
56+
* @param value Source stac item,
57+
* @param href href to convert
58+
* @returns absolute URL if able to be converted
59+
*/
60+
export function makeAbsoluteUrl(
61+
value?: StacValue,
62+
href?: string,
63+
): string | undefined {
64+
if (href == null || value == null) return href;
65+
const sourceUrl = (value as StacValueWithSource)[SourceKey];
66+
if (sourceUrl == null) return href;
67+
return new URL(href, sourceUrl).toString();
68+
}

0 commit comments

Comments
 (0)