/** 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?: undefined | ((endereco: 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({ caminhos, acaoIr, }: { caminhos: string[] | string; acaoIr: (endereco: string) => undefined }) { this._acaoIr = acaoIr ;[Array.isArray(caminhos) ? caminhos : [caminhos]].forEach((caminho) => { String(caminho) .split("/") .forEach((parte) => { if (parte) { this._partesCaminho.push(parte) } }) }) } /** Retorna o caminho completo da rota ** console.log(mCaminho.caminho) ** "/caminho" */ get caminho() { let ret = `/${this._partesCaminho.join("/")}` ret = ret.replace(/\/+/g, "/") if (ret.length > 1 && ret.endsWith("/")) { ret = ret.slice(0, -1) } 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), value === undefined || value === null ? "" : 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"} */ get parametros() { const url = new URL( typeof window !== "undefined" ? window.location.href : "http://localhost", ) const query = url.searchParams const queryObj = Object.fromEntries(query.entries()) // pegar hash const hash = url.hash if (hash) { const hashObj = Object.fromEntries( new URLSearchParams(hash.slice(1)).entries(), ) return { ...queryObj, ...hashObj } as T } return queryObj as Partial } }