iopa
Version:
API-first, Internet of Things (IoT) stack for Typescript, official implementation of the Internet Open Protocols Alliance (IOPA) reference pattern
105 lines (87 loc) • 2.23 kB
text/typescript
import { UrlPattern } from '@iopa/types'
/* eslint-disable @rushstack/security/no-unsafe-regexp */
const URL_REGEXP: RegExp = /^https?:\/\/[a-zA-Z0-9\-\.:]+(\/?[^?#]*)/
export const splitPath = (path: string): string[] => {
const paths = path.split(/\//) // faster than path.split('/')
if (paths[0] === '') {
paths.shift()
}
return paths
}
const patternCache: { [key: string]: UrlPattern } = {}
export const getPattern = (label: string): UrlPattern | null => {
// * => wildcard
// :id{[0-9]+} => ([0-9]+)
// :id => (.+)
//const name = ''
if (label === '*') {
return '*'
}
const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/)
if (match) {
if (!patternCache[label]) {
if (match[2]) {
patternCache[label] = [
label,
match[1],
new RegExp('^' + match[2] + '$')
]
} else {
patternCache[label] = [label, match[1], true]
}
}
return patternCache[label]
}
return null
}
interface IParams {
strict: boolean
}
export const getPathFromURL = (
url: string,
params: IParams = { strict: true }
): string => {
// if strict routing is false => `/hello/hey/` and `/hello/hey` are treated the same
// default is true
if (params.strict === false && url.endsWith('/')) {
url = url.slice(0, -1)
}
const match = url.match(URL_REGEXP)
if (match) {
return match[1]
}
return ''
}
export const isAbsoluteURL = (url: string): boolean => {
const match = url.match(URL_REGEXP)
if (match) {
return true
}
return false
}
export const mergePath = (...paths: string[]): string => {
let p: string = ''
let endsWithSlash = false
for (let path of paths) {
/* ['/hey/','/say'] => ['/hey', '/say'] */
if (p.endsWith('/')) {
p = p.slice(0, -1)
endsWithSlash = true
}
/* ['/hey','say'] => ['/hey', '/say'] */
if (!path.startsWith('/')) {
path = `/${path}`
}
/* ['/hey/', '/'] => `/hey/` */
if (path === '/' && endsWithSlash) {
p = `${p}/`
} else if (path !== '/') {
p = `${p}${path}`
}
/* ['/', '/'] => `/` */
if (path === '/' && p === '') {
p = '/'
}
}
return p
}