Created
May 21, 2022 01:16
-
-
Save jchild3rs/374f0c8645ccecd79b762fb01fd71821 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import "buffer"; | |
import P from "parsimmon"; | |
import { NextRequest, NextResponse } from "next/server"; | |
/** State and city tokens are just letters */ | |
const dashToken = P.string("-"); | |
const slashToken = P.string("/"); | |
const zipPrefixToken = P.regex(/zip-/i); | |
const zipToken = P.regex(/[\d]+/i); | |
const poiToken = P.string("/p"); | |
const stateToken = P.regex(/[a-z]+/i); | |
const locationToken = P.regex(/[a-z]+/i); | |
const refinementsToken = P.regex(/[\w]+/i); | |
/** The "-apartments" token represents all property types */ | |
const allPropertiesToken = P.string("apartments").map(() => [ | |
"apartments", | |
"condos", | |
"houses", | |
"townhouses", | |
]); | |
/** Other property types map to their defined properties */ | |
const condosToken = P.string("condos").map(() => ["condos"]); | |
const housesToken = P.string("houses").map(() => ["houses"]); | |
const townhousesToken = P.string("townhouses").map(() => ["townhouses"]); | |
/** A valid property type is any of the above tokens */ | |
const propertyTypeToken = P.alt( | |
allPropertiesToken, | |
condosToken, | |
housesToken, | |
townhousesToken | |
); | |
const propertyTypesAndMaybeRefinementsToken = P.alt( | |
P.seq(propertyTypeToken.skip(slashToken), refinementsToken).map( | |
([propertyType, refinements]) => ({ | |
propertyType, | |
refinements: refinements?.split("_"), | |
}) | |
), | |
propertyTypeToken.map((propertyType) => ({ | |
propertyType, | |
})) | |
); | |
const zipRouteToken = P.seq( | |
slashToken.skip(zipPrefixToken), | |
zipToken.skip(dashToken), | |
propertyTypesAndMaybeRefinementsToken | |
).map(([_, zipCode, propertyTypeAndMaybeRefinements]) => ({ | |
zipCode, | |
...propertyTypeAndMaybeRefinements, | |
})); | |
const poiRouteToken = P.seq( | |
poiToken.skip(slashToken), | |
stateToken.skip(slashToken), | |
locationToken.skip(dashToken), | |
propertyTypesAndMaybeRefinementsToken | |
).map(([_, state, location, propertyTypeAndMaybeRefinements]) => ({ | |
state, | |
location, | |
...propertyTypeAndMaybeRefinements, | |
})); | |
const cityStateRouteToken = P.seq( | |
slashToken, | |
stateToken.skip(slashToken), | |
locationToken.skip(dashToken), | |
propertyTypesAndMaybeRefinementsToken | |
).map(([_, state, location, propertyTypeAndMaybeRefinements]) => ({ | |
state, | |
location, | |
...propertyTypeAndMaybeRefinements, | |
})); | |
const searchParser = P.alt(poiRouteToken, zipRouteToken, cityStateRouteToken); | |
export function middleware(req: NextRequest) { | |
const url: URL = req.nextUrl; | |
const result = searchParser.parse(url.pathname); | |
if (result.status) { | |
console.log(result.value); | |
url.pathname = "/search"; | |
for (const key of Object.keys(result.value)) { | |
const value = result.value[key]; | |
if (Array.isArray(value)) { | |
value.forEach((val) => { | |
url.searchParams.append(key, val); | |
}); | |
} else { | |
url.searchParams.append(key, value); | |
} | |
} | |
return NextResponse.rewrite(url); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment