const POST_NEW_REVIEW_PATH_PREFIX = '/posts/new?urls=' const MAX_POST_NEW_REVIEW_TARGET_BYTES = 6_144 const textEncoder = new TextEncoder () const rawUrlsParam = (search: string): string | null => { const query = search.startsWith ('?') ? search.slice (1) : search if (query === '') return null for (const segment of query.split ('&')) { if (segment === 'urls') return '' if (segment.startsWith ('urls=')) return segment.slice ('urls='.length) } return null } export const buildPostNewReviewPath = (urls: string[]): string => `${ POST_NEW_REVIEW_PATH_PREFIX }${ urls.map (url => encodeURIComponent (url)).join ('+') }` export const postNewReviewPathByteLength = (urls: string[]): number => textEncoder.encode (buildPostNewReviewPath (urls)).byteLength export const isPostNewReviewPathWithinLimit = (urls: string[]): boolean => postNewReviewPathByteLength (urls) < MAX_POST_NEW_REVIEW_TARGET_BYTES export const parsePostNewReviewUrls = (search: string): string[] => { const raw = rawUrlsParam (search) if (raw == null) return [] return raw .split ('+') .filter (segment => segment !== '') .map (segment => { try { return decodeURIComponent (segment) } catch { return segment } }) } export const hasPostNewReviewState = (search: string): boolean => rawUrlsParam (search) != null