/** Gerar uma classe que facilita a gestão de rotas com a tipagem das querys * * Definições: * * caminho = "/aplicacao/funcionalidade" * * endereco = "http://localhost:3000/aplicacao/funcionalidade" * * parametros = {nome:"José"} */ export class TipagemRotas { _partesCaminho: string[] = [] _acaoIr?: (endereco: string) => undefined rotulo: string | undefined /** Ao criar novo obijeto de tipagem de rota é necessário passar o caminho parcial ** export const mCaminho = new TipagemRotas<{q:string}>("aplicacao","funcionalidade") */ constructor({ caminho, acaoIr, rotulo, }: { caminho: (string | null | undefined)[] | string acaoIr?: undefined | ((endereco: string) => undefined) /** Rotulo da página * Inicio | Controle */ rotulo?: string }) { this._acaoIr = acaoIr this._partesCaminho = (Array.isArray(caminho) ? caminho : [caminho]) .filter(Boolean) .map((a) => String(a)) .flatMap((a) => a.split("/")) .filter(Boolean) this.rotulo = rotulo } /** Retorna o caminho completo da rota ** console.log(mCaminho.caminho) ** "/caminho" */ get caminho() { const ret = `/${this._partesCaminho.join("/")}` return ret } /** Define o caminho completo da rota ** mCaminho.caminho = "/novoCaminho" ** console.log(mCaminho.caminho) ** "/novoCaminho" ** */ set caminho(caminhoParcial: string) { this._partesCaminho = caminhoParcial.split("/").filter((parte) => parte) } /** Retorna o caminho completo da rota com a query ** console.log(mCaminho.resolve({q:"query"})) ** "http://localhost:3000/caminho?q=query" */ endereco(query: T, usarComoHash?: boolean) { const url = new URL( typeof window !== "undefined" ? window.location.href : "http://localhost", ) url.pathname = this.caminho url.search = "" const queryKeys = Object.entries(query) for (const [key, value] of queryKeys) { url.searchParams.set(String(key), JSON.stringify(value)) } url.hash = "" if (usarComoHash) { url.hash = `#${url.search}` url.search = "" } return url.href } /** Vai para a url ** mCaminho.ir({q:"query"}) ** window.location.href = "http://localhost:3000/caminho?q=query" */ ir(query: T) { if (this._acaoIr) { this._acaoIr(this.endereco({ ...query })) } else { if (typeof window != "undefined") { window.location.href = this.endereco({ ...query }) } } } /** Retorna os parametros da url ** console.log(mCaminho.parametros()) ** {q:"query"} */ parametros(urlEntrada?: string) { const url = urlEntrada ? new URL(urlEntrada) : new URL( typeof window !== "undefined" ? window.location.href : "http://localhost", ) const query = url.searchParams let queryObj = Object.fromEntries(query.entries()) // pegar hash const hash = url.hash if (hash) { const hashObj = Object.fromEntries( new URLSearchParams(hash.slice(1)).entries(), ) queryObj = { ...queryObj, ...hashObj } as T } for (const chave in queryObj) { try { queryObj[chave] = JSON.parse(queryObj[chave]) } catch { console.log(`[${chave}|${queryObj[chave]}] não é um json válido.`) } } return queryObj as Partial } }