@@ -16,7 +16,7 @@ export async function fetchStac(
16
16
if ( response . ok ) {
17
17
return response
18
18
. json ( )
19
- . then ( ( json ) => maybeAddSelfLink ( json , href . toString ( ) ) ) ;
19
+ . then ( ( json ) => makeStacUrlAbsolute ( json , href . toString ( ) ) ) ;
20
20
} else {
21
21
throw new Error ( `${ method } ${ href } : ${ response . statusText } ` ) ;
22
22
}
@@ -32,9 +32,8 @@ export async function fetchStacLink(link: StacLink, href?: string | undefined) {
32
32
) ;
33
33
}
34
34
35
- // eslint-disable-next-line
36
- function maybeAddSelfLink ( value : any , href : string ) {
37
- if ( ! ( value as StacValue ) ?. links ?. find ( ( link ) => link . rel == "self" ) ) {
35
+ function maybeAddSelfLink ( value : StacValue , href : string ) {
36
+ if ( ! value ?. links ?. find ( ( link ) => link . rel == "self" ) ) {
38
37
const link = { href, rel : "self" } ;
39
38
if ( Array . isArray ( value . links ) ) {
40
39
value . links . push ( link ) ;
@@ -44,3 +43,71 @@ function maybeAddSelfLink(value: any, href: string) {
44
43
}
45
44
return value ;
46
45
}
46
+
47
+ /**
48
+ * Attempt to convert links and asset URLS to absolute URLs while ensuring a self link exists.
49
+ *
50
+ * @param value Source stac item, collection, or catalog
51
+ * @param baseUrl base location of the STAC document
52
+ */
53
+ export function makeStacUrlAbsolute < T extends StacValue > (
54
+ value : T ,
55
+ baseUrl : string ,
56
+ ) : T {
57
+ maybeAddSelfLink ( value , baseUrl ) ;
58
+ const baseUrlObj = new URL ( baseUrl ) ;
59
+
60
+ if ( value . links != null ) {
61
+ for ( const link of value . links ) {
62
+ if ( link . href == null ) continue ;
63
+ link . href = toAbsoluteUrl ( link . href , baseUrlObj ) ;
64
+ }
65
+ }
66
+
67
+ if ( value . assets != null ) {
68
+ for ( const asset of Object . values ( value . assets ) ) {
69
+ if ( asset . href == null ) continue ;
70
+ asset . href = toAbsoluteUrl ( asset . href , baseUrlObj ) ;
71
+ }
72
+ }
73
+ return value ;
74
+ }
75
+
76
+ /**
77
+ * Determine if the URL is absolute
78
+ * @returns true if absolute, false otherwise
79
+ */
80
+ function isAbsolute ( url : string ) {
81
+ try {
82
+ new URL ( url ) ;
83
+ return true ;
84
+ } catch {
85
+ return false ;
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Attempt to convert a possibly relative URL to an absolute URL
91
+ *
92
+ * If the URL is already absolute, it is returned unchanged.
93
+ *
94
+ * **WARNING**: if the URL is http it will be returned as URL encoded
95
+ *
96
+ * @param href
97
+ * @param baseUrl
98
+ * @returns absolute URL
99
+ */
100
+ export function toAbsoluteUrl ( href : string , baseUrl : URL ) : string {
101
+ if ( isAbsolute ( href ) ) return href ;
102
+
103
+ const targetUrl = new URL ( href , baseUrl ) ;
104
+
105
+ if ( targetUrl . protocol === "http:" || targetUrl . protocol === "https:" ) {
106
+ return targetUrl . toString ( ) ;
107
+ }
108
+
109
+ // S3 links should not be encoded
110
+ if ( targetUrl . protocol === "s3:" ) return decodeURI ( targetUrl . toString ( ) ) ;
111
+
112
+ return targetUrl . toString ( ) ;
113
+ }
0 commit comments