in packages/core/src/shared/clients/s3.ts [705:784]
export function parseS3Uri(uri: string): [region: string, bucket: string, key: string] {
const endpointPattern = /^(.+\.)?s3[.-]([a-z0-9-]+)\./
const defaultRegion = 'us-east-1' // Default region for URI parsing, if region is not found
const parsedUri = url.parse(uri)
let bucket: string | undefined = undefined
let region: string = defaultRegion
let key: string | undefined = undefined
if (parsedUri.protocol === 's3:') {
bucket = parsedUri.host ?? undefined
if (!bucket) {
throw new Error(`Invalid S3 URI: no bucket: ${uri}`)
}
if (!parsedUri.pathname || parsedUri.pathname.length <= 1) {
// s3://bucket or s3://bucket/
key = undefined
} else {
// s3://bucket/key
// Remove the leading '/'.
key = parsedUri.pathname.substring(1)
}
if (key !== undefined) {
key = decodeURIComponent(key)
}
return [region, bucket, key!]
}
if (!parsedUri.host) {
throw new Error(`Invalid S3 URI: no hostname: ${uri}`)
}
const matches = parsedUri.host.match(endpointPattern)
if (!matches) {
throw new Error(`Invalid S3 URI: hostname does not appear to be a valid S3 endpoint: ${uri}`)
}
const prefix = matches[1]
if (!prefix) {
if (parsedUri.pathname === '/') {
bucket = undefined
key = undefined
} else {
const index = parsedUri.pathname!.indexOf('/', 1)
if (index === -1) {
// https://s3.amazonaws.com/bucket
bucket = parsedUri.pathname!.substring(1) ?? undefined
key = undefined
} else if (index === parsedUri.pathname!.length - 1) {
// https://s3.amazonaws.com/bucket/
bucket = parsedUri.pathname!.substring(1, index)
key = undefined
} else {
// https://s3.amazonaws.com/bucket/key
bucket = parsedUri.pathname!.substring(1, index)
key = parsedUri.pathname!.substring(index + 1)
}
}
} else {
// Remove the trailing '.' from the prefix to get the bucket.
bucket = prefix.substring(0, prefix.length - 1)
if (!parsedUri.pathname || parsedUri.pathname === '/') {
key = undefined
} else {
// Remove the leading '/'.
key = parsedUri.pathname.substring(1)
}
}
if (matches[2] !== 'amazonaws') {
region = matches[2]
} else {
region = defaultRegion
}
if (key !== undefined) {
key = decodeURIComponent(key)
}
return [region, bucket!, key!]
}