Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

notehost

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

notehost - npm Package Compare versions

Comparing version
1.0.32
to
1.0.33
+1
-1
dist/cli/index.js

@@ -7,3 +7,3 @@ #!/usr/bin/env node

// package.json
var version = "1.0.32";
var version = "1.0.33";

@@ -10,0 +10,0 @@ // src/cli/init-repo.ts

@@ -151,4 +151,5 @@ var __defProp = Object.defineProperty;

// console.log('redirected', getSlug())
updateSlug()
redirected = true
updateSlug()
addDarkModeButton(nav ? 'web' : 'mobile')

@@ -181,4 +182,12 @@

const { replaceState } = window.history
const { replaceState, back, forward } = window.history
window.history.back = function () {
back.apply(window.history, arguments)
}
window.history.forward = function () {
forward.apply(window.history, arguments)
}
window.history.replaceState = function () {

@@ -189,8 +198,11 @@ if (arguments[1] === 'bypass') {

// console.log('replaceState arguments:', arguments)
// console.log('replaceState state:', state)
const slug = getSlug()
const isKnownSlug = slugs.includes(slug)
if (isKnownSlug && location.pathname !== ['/', slug].join('')) {
console.log('replaceState:', { slug, isKnownSlug, arguments })
// console.log('replaceState arguments:', arguments)
// console.log('replaceState state:', state)
if (arguments[2] === '/login') {
const page = SLUG_TO_PAGE[slug]

@@ -202,3 +214,11 @@

arguments[2] = ['/', page].join('')
replaceState.apply(window.history, arguments)
window.location.reload()
return
}
} else {
if (isKnownSlug && arguments[2] !== ['/', slug].join('')) {
return
}
}

@@ -539,7 +559,13 @@

}
const slugHash = url.pathname.split("/").pop().split("-").pop();
const page = slugToPage[slugHash];
console.log("url.pathname", url.pathname);
const slug = url.pathname.split("/").pop();
const slugHash = url.pathname.slice(-32);
const page = slugToPage[slug];
if (page) {
console.log(`Redirecting ${slug} to https://${domain}/${page}`);
return Response.redirect(`https://${domain}/${page}`, 301);
} else if (slugHash.length !== 32 && !slugHash.match(/^[0-9a-f]+$/i)) {
} else if (slugHash && slugHash !== slug && slugHash.length === 32) {
console.log(`Redirecting ${slug} to https://${domain}/${slugHash}`);
return Response.redirect(`https://${domain}/${slugHash}`, 301);
} else if (slug && slug.length !== 32) {
if (siteConfig.fof?.page?.length) {

@@ -546,0 +572,0 @@ return Response.redirect(`https://${domain}/${siteConfig.fof.page}`, 301);

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/index.ts","../src/config-helpers.ts","../src/rewriters/_body-js-string.ts","../src/rewriters/body-rewriter.ts","../src/rewriters/head-rewriter.ts","../src/rewriters/meta-rewriter.ts","../src/append-js.ts","../src/append-js-pf.ts","../src/handlers/handle-favicon.ts","../src/handlers/handle-other.ts","../src/handlers/handle-api.ts","../src/handlers/handle-app-js.ts","../src/handlers/handle-js.ts","../src/handlers/handle-options.ts","../src/handlers/handle-sitemap.ts","../src/reverse-proxy-init.ts","../src/reverse-proxy.ts"],"sourcesContent":["export * from './config-helpers'\nexport * from './reverse-proxy'\nexport { initializeReverseProxy } from './reverse-proxy-init'\nexport * from './types'\n","export function googleTag(googleTagId: string) {\n return `\n <!-- Google tag (gtag.js) -->\n <script async src=\"https://www.googletagmanager.com/gtag/js?id=${googleTagId}\"></script>\n <script>\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n \n gtag('config', '${googleTagId}');\n </script>\n `\n}\n","export const BODY_JS_STRING = `\n/* eslint-disable no-unused-vars */\n/* eslint-disable prefer-rest-params */\n/* eslint-disable no-lonely-if */\n/* eslint-disable no-restricted-globals */\n/* eslint-disable no-underscore-dangle */\n/* eslint-disable no-undef */\nlocalStorage.__console = true\n\nconst el = document.createElement('div')\nlet redirected = false\n\nfunction getPage() {\n return location.pathname.slice(-32)\n}\n\nfunction getSlug() {\n return location.pathname.slice(1)\n}\n\nfunction updateSlug() {\n const slug = PAGE_TO_SLUG[getPage()]\n\n if (slug != null) {\n history.replaceState(history.state, '', ['/', slug].join(''))\n }\n}\n\nfunction enableConsoleEffectAndSetMode(mode) {\n if (__console && !__console.isEnabled) {\n __console.enable()\n window.location.reload()\n } else {\n __console?.environment?.ThemeStore?.setState({ mode })\n localStorage.setItem('newTheme', JSON.stringify({ mode }))\n }\n}\n\nfunction onDark() {\n el.innerHTML =\n '<div title=\"Change to Light Mode\" style=\"margin-left: 14px; margin-right: 14px; min-width: 0px;\"><div role=\"button\" tabindex=\"0\" style=\"user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;\"><div style=\"display: flex; flex-shrink: 0; height: 14px; width: 26px; padding: 2px; box-sizing: content-box; border-radius: 44px; border-style: solid; border-width: 0.1em; border-color: #D4D4D4; transition: background 200ms ease 0s, box-shadow 200ms ease 0s;\"><div style=\"width: 14px; height: 14px; border-radius: 44px; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(12px) translateY(0px); content: url(&quot;https://svgshare.com/i/12Tz.svg&quot;);\"></div></div></div></div>'\n document.body.classList.add('dark')\n enableConsoleEffectAndSetMode('dark')\n}\n\nfunction onLight() {\n el.innerHTML =\n '<div title=\"Change to Dark Mode\" style=\"margin-left: 14px; margin-right: 14px; min-width: 0px;\"><div role=\"button\" tabindex=\"0\" style=\"user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;\"><div style=\"display: flex; flex-shrink: 0; height: 14px; width: 26px; padding: 2px; box-sizing: content-box; border-radius: 44px; border-style: solid; border-width: 0.1em; border-color: #6D6C68; transition: background 200ms ease 0s, box-shadow 200ms ease 0s;\"><div style=\"width: 14px; height: 14px; border-radius: 44px; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(0px) translateY(0px); content: url(&quot;https://svgshare.com/i/12VG.svg&quot;);\"></div></div></div></div>'\n document.body.classList.remove('dark')\n enableConsoleEffectAndSetMode('light')\n}\n\nfunction toggle() {\n if (document.body.classList.contains('dark')) {\n onLight()\n } else {\n onDark()\n }\n}\n\nfunction addDarkModeButton(device) {\n const nav =\n device === 'web'\n ? document.querySelector('.notion-topbar').firstChild\n : document.querySelector('.notion-topbar-mobile')\n\n el.className = 'toggle-mode'\n el.addEventListener('click', toggle)\n\n const timeout = device === 'web' ? 0 : 500\n\n setTimeout(() => {\n nav.appendChild(el)\n }, timeout)\n\n // get the current theme and add the toggle to represent that theme\n const currentTheme = JSON.parse(localStorage.getItem('newTheme'))?.mode\n\n if (currentTheme) {\n if (currentTheme === 'dark') {\n onDark()\n } else {\n onLight()\n }\n } else {\n // enable smart dark mode based on user-preference\n if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n onDark()\n } else {\n onLight()\n }\n }\n\n // try to detect if user-preference change\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {\n toggle()\n })\n}\n\nconst observer = new MutationObserver(() => {\n if (redirected) return\n\n const nav = document.querySelector('.notion-topbar')\n const mobileNav = document.querySelector('.notion-topbar-mobile')\n\n if ((nav && nav.firstChild && nav.firstChild.firstChild) || (mobileNav && mobileNav.firstChild)) {\n // console.log('redirected', getSlug())\n redirected = true\n updateSlug()\n addDarkModeButton(nav ? 'web' : 'mobile')\n\n const { onpopstate } = window\n\n window.onpopstate = function () {\n // console.log('onpopstate');\n if (slugs.includes(getSlug())) {\n const page = SLUG_TO_PAGE[getSlug()]\n\n if (page) {\n // console.log('slug:', getSlug())\n // console.log('redirecting to:', page)\n history.replaceState(history.state, 'bypass', ['/', page].join(''))\n }\n }\n\n onpopstate.apply(this, [].slice.call(arguments))\n updateSlug()\n }\n }\n})\n\nobserver.observe(document.querySelector('#notion-app'), {\n childList: true,\n subtree: true,\n})\n\nconst { replaceState } = window.history\n\nwindow.history.replaceState = function () {\n if (arguments[1] === 'bypass') {\n return\n }\n\n // console.log('replaceState arguments:', arguments)\n // console.log('replaceState state:', state)\n const slug = getSlug()\n const isKnownSlug = slugs.includes(slug)\n\n if (isKnownSlug && location.pathname !== ['/', slug].join('')) {\n const page = SLUG_TO_PAGE[slug]\n\n if (page) {\n // console.log('slug:', slug)\n // console.log('redirecting to:', page)\n arguments[2] = ['/', page].join('')\n }\n }\n\n replaceState.apply(window.history, arguments)\n}\n\nconst { pushState } = window.history\n\nwindow.history.pushState = function () {\n const dest = new URL(location.protocol + location.host + arguments[2])\n const id = dest.pathname.slice(-32)\n\n // console.log('pushState state:', state)\n // console.log('pushState id:', id)\n if (pages.includes(id)) {\n arguments[2] = ['/', PAGE_TO_SLUG[id]].join('')\n }\n\n return pushState.apply(window.history, arguments)\n}\n\nconst { open } = window.XMLHttpRequest.prototype\n\nwindow.XMLHttpRequest.prototype.open = function () {\n arguments[1] = arguments[1].replace(domain, notionDomain)\n\n if (arguments[1].indexOf('msgstore.' + notionDomain) > -1) {\n return\n }\n\n // console.log('XMLHttpRequest.open arguments:', arguments)\n open.apply(this, [].slice.call(arguments))\n}\n`\n","import { NoteHostSiteConfigFull } from '../types'\nimport { BODY_JS_STRING } from './_body-js-string'\n/* eslint-disable class-methods-use-this */\nexport class BodyRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n constructor(siteConfig: NoteHostSiteConfigFull) {\n this.siteConfig = siteConfig\n }\n\n element(element: Element) {\n const { domain, slugToPage, pageToSlug, slugs, pages, customBodyJS } = this.siteConfig\n\n element.append(\n `\n <script>\n const domain = '${domain}';\n window.CONFIG.domainBaseUrl = 'https://${domain}';\n const SLUG_TO_PAGE = ${JSON.stringify(slugToPage)};\n const PAGE_TO_SLUG = ${JSON.stringify(pageToSlug)};\n const slugs = ${JSON.stringify(slugs)};\n const pages = ${JSON.stringify(pages)};\n const notionDomain = '${this.siteConfig.notionDomain ? this.siteConfig.notionDomain : 'www.notion.so'}';\n ${BODY_JS_STRING}\n </script>\n ${customBodyJS ?? ''}\n `,\n {\n html: true,\n },\n )\n }\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\n/* eslint-disable class-methods-use-this */\nexport class HeadRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n constructor(siteConfig: NoteHostSiteConfigFull) {\n this.siteConfig = siteConfig\n }\n\n element(element: Element) {\n const { googleFont, customHeadJS, customHeadCSS } = this.siteConfig\n\n if (googleFont) {\n element.append(\n `<link href='https://fonts.googleapis.com/css?family=${googleFont.replace(\n ' ',\n '+',\n )}:Regular,Bold,Italic&display=swap' rel='stylesheet'>\n <style>* { font-family: \"${googleFont}\" !important; }</style>`,\n {\n html: true,\n },\n )\n }\n\n element.append(\n `<style>\n div.notion-topbar > div > div:nth-child(3) { display: none !important; }\n div.notion-topbar > div > div:nth-child(4) { display: none !important; }\n div.notion-topbar > div > div:nth-child(5) { display: none !important; }\n div.notion-topbar > div > div:nth-child(6) { display: none !important; }\n div.notion-topbar > div > div:nth-child(7) { display: none !important; }\n div.notion-topbar > div > div:nth-child(1n).toggle-mode { display: block !important; }\n \n div.notion-topbar-mobile > div:nth-child(3) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(4) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(7) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(1n).toggle-mode { display: block !important; }\n ${customHeadCSS ?? ''}\n </style>\n ${customHeadJS ?? ''}`,\n {\n html: true,\n },\n )\n }\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\n/* eslint-disable class-methods-use-this */\nexport class MetaRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n url: URL\n\n isRootPage: boolean\n\n constructor(siteConfig: NoteHostSiteConfigFull, url: URL) {\n this.siteConfig = siteConfig\n this.url = url\n this.isRootPage = this.siteConfig.pageToSlug[this.url.pathname.slice(1)] === ''\n }\n\n element(element: Element) {\n const { siteName, siteDescription, twitterHandle, siteImage, domain, pageToSlug, pageMetadata } = this.siteConfig\n const page = this.url.pathname.slice(-32)\n const property = element.getAttribute('property') ?? ''\n const name = element.getAttribute('name') ?? ''\n const content = element.getAttribute('content') ?? ''\n\n // console.log(\n // `${this.url}: <${element.tagName} name=\"${name}\" property=\"${property}\">${content}</${element.tagName}>`,\n // )\n\n if (element.tagName === 'title') {\n const pageTitle = pageMetadata[page]?.title ?? removeNotionAds(content)\n\n element.setInnerContent(pageTitle)\n }\n\n if (property === 'og:title' || name === 'twitter:title') {\n const pageTitle = pageMetadata[page]?.title ?? removeNotionAds(content)\n\n element.setAttribute('content', pageTitle)\n }\n\n if (property === 'og:site_name') {\n element.setAttribute('content', siteName)\n }\n\n if (name === 'article:author') {\n const pageAuthor = pageMetadata[page]?.author ?? content\n\n element.setAttribute('content', pageAuthor)\n }\n\n if (name === 'description' || property === 'og:description' || name === 'twitter:description') {\n if (this.isRootPage) {\n element.setAttribute('content', siteDescription)\n } else {\n const pageDescription = pageMetadata[page]?.description ?? removeNotionAds(content)\n\n element.setAttribute('content', pageDescription)\n }\n }\n\n if (property === 'og:url' || name === 'twitter:url') {\n if (this.isRootPage) {\n element.setAttribute('content', `https://${domain}/`)\n } else if (pageToSlug[page]) {\n element.setAttribute('content', `https://${domain}/${pageToSlug[page]}`)\n } else {\n element.setAttribute('content', `https://${domain}/${page}`)\n }\n }\n\n if (name === 'twitter:site') {\n if (twitterHandle) {\n element.setAttribute('content', `${twitterHandle}`)\n } else {\n element.remove()\n }\n }\n\n if (property === 'og:image' || name === 'twitter:image') {\n if (this.isRootPage && siteImage) {\n // console.log(`----- Image for url '${this.url.pathname}: ${siteImage}'`)\n element.setAttribute('content', siteImage)\n } else {\n const pageImage = pageMetadata[page]?.image ?? content\n // console.log(`----- Image for url '${this.url.pathname}: ${pageImage}'`)\n\n element.setAttribute('content', pageImage)\n }\n }\n\n if (name === 'apple-itunes-app') {\n element.remove()\n }\n }\n}\n\nfunction removeNotionAds(text: string) {\n return text\n .replace(' | Built with Notion', '')\n .replace(' | Notion', '')\n .replace('Built with Notion, the all-in-one connected workspace with publishing capabilities.', '')\n}\n","import { MetaRewriter, HeadRewriter, BodyRewriter } from './rewriters'\nimport { NoteHostSiteConfigFull } from './types'\n\nexport async function appendJavascript(res: Response, url: URL, config: NoteHostSiteConfigFull) {\n // eslint-disable-next-line no-undef\n return new HTMLRewriter()\n .on('title', new MetaRewriter(config, url))\n .on('meta', new MetaRewriter(config, url))\n .on('head', new HeadRewriter(config))\n .on('body', new BodyRewriter(config))\n .transform(res)\n}\n","import { HTMLRewriter } from 'htmlrewriter'\nimport { NoteHostSiteConfigFull } from '.'\nimport { BodyRewriter, HeadRewriter, MetaRewriter } from './rewriters'\n\nexport async function appendJavascriptPolyfill(res: Response, url: URL, config: NoteHostSiteConfigFull) {\n // eslint-disable-next-line no-undef\n return new HTMLRewriter()\n .on('title', new MetaRewriter(config, url) as any)\n .on('meta', new MetaRewriter(config, url) as any)\n .on('head', new HeadRewriter(config) as any)\n .on('body', new BodyRewriter(config) as any)\n .transform(res)\n}\n","export async function handleFavicon(url: URL, siteIcon: string) {\n const response = await fetch(siteIcon)\n const body = await response.arrayBuffer()\n const ret = new Response(body, response)\n\n return ret\n}\n","export async function handleNotionAsset(url: URL) {\n const response = await fetch(url.toString())\n const body = await response.arrayBuffer()\n const ret = new Response(body, response)\n\n return ret\n}\n","/* eslint-disable no-undef */\nexport async function handleApi(url: URL, request: Request) {\n // Forward API\n const response = await fetch(url.toString(), {\n body: url.pathname.startsWith('/api/v3/getPublicPageData') ? null : request.body,\n headers: {\n 'content-type': 'application/json;charset=UTF-8',\n 'user-agent':\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',\n },\n method: 'POST',\n })\n const ret = new Response(response.body as BodyInit, response)\n\n ret.headers.set('Access-Control-Allow-Origin', '*')\n\n return ret\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\nexport async function handleAppJs(url: URL, siteConfig: NoteHostSiteConfigFull) {\n const { domain } = siteConfig\n const response = await fetch(url.toString())\n const body = await response.text()\n const siteRegex = new RegExp(\n siteConfig.notionDomain ? `${siteConfig.notionDomain}.notion.site` : 'www.notion.so',\n 'g',\n )\n const ret = new Response(body.replace(siteRegex, domain).replace(/notion.so/g, domain), response)\n\n ret.headers.set('Content-Type', 'application/x-javascript')\n\n return ret\n}\n","export async function handleJs(url: URL) {\n const response = await fetch(url.toString())\n const body = await response.text()\n const ret = new Response(body, response)\n\n ret.headers.set('Content-Type', 'application/x-javascript')\n\n return ret\n}\n","const corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n}\n\nexport function handleOptions(request: Request) {\n if (\n request.headers.get('Origin') !== null &&\n request.headers.get('Access-Control-Request-Method') !== null &&\n request.headers.get('Access-Control-Request-Headers') !== null\n ) {\n // Handle CORS pre-flight request.\n return new Response(null, {\n headers: corsHeaders,\n })\n }\n\n // Handle standard OPTIONS request.\n return new Response(null, {\n headers: {\n Allow: 'GET, HEAD, POST, PUT, OPTIONS',\n },\n })\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\nexport function handleSitemap(request: Request, siteConfig: NoteHostSiteConfigFull) {\n const { domain, slugs } = siteConfig\n let sitemap = '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">'\n\n slugs.forEach((slug) => {\n sitemap += `<url><loc>https://${domain}/${slug}</loc></url>`\n })\n sitemap += '</urlset>'\n\n const response = new Response(sitemap)\n\n response.headers.set('content-type', 'application/xml')\n\n return response\n}\n","import { NoteHostSiteConfig, NoteHostSiteConfigFull } from './types'\n\nexport let siteConfig: NoteHostSiteConfigFull = {} as NoteHostSiteConfigFull\n\nexport function initializeReverseProxy(siteConfigUser: NoteHostSiteConfig) {\n siteConfig = {\n ...siteConfigUser,\n slugs: [],\n pages: [],\n pageToSlug: {},\n }\n\n siteConfig.pageMetadata = siteConfig.pageMetadata || {}\n\n siteConfig.fof = {\n page: siteConfig.fof?.page,\n slug: siteConfig.fof?.slug || '404',\n }\n\n if (siteConfig.fof.page?.length) {\n siteConfig.slugToPage[siteConfig.fof.slug] = siteConfig.fof.page\n }\n\n // Build helper indexes for worker and for the client (body.js)\n Object.keys(siteConfig.slugToPage).forEach((slug) => {\n const pageId = siteConfig.slugToPage[slug]\n\n siteConfig.slugs.push(slug)\n siteConfig.pages.push(pageId)\n siteConfig.pageToSlug[pageId] = slug\n })\n}\n","/* eslint-disable no-undef */\nimport { appendJavascript } from './append-js'\nimport { appendJavascriptPolyfill } from './append-js-pf'\nimport { handleFavicon } from './handlers/handle-favicon'\nimport { handleNotionAsset } from './handlers/handle-other'\nimport { handleApi, handleAppJs, handleJs, handleOptions, handleSitemap } from './handlers/index'\nimport { siteConfig } from './reverse-proxy-init'\n\nexport async function reverseProxy(\n request: Request,\n opts: {\n cloudflare: boolean\n } = { cloudflare: true },\n) {\n const { cloudflare } = opts\n\n if (!siteConfig) {\n throw new Error('Site config is not initialized. Please call initializeReverseProxy() first.')\n }\n\n const { domain, slugToPage, siteIcon } = siteConfig\n\n if (request.method === 'OPTIONS') {\n return handleOptions(request)\n }\n\n const url = new URL(request.url)\n const subDomain = url.hostname.split('.')[0]\n\n if (url.hostname === domain) {\n url.hostname = siteConfig.notionDomain ? `${siteConfig.notionDomain}.notion.site` : 'www.notion.so'\n\n // Handle special Notion routes\n if (url.pathname === '/robots.txt') {\n return new Response(`Sitemap: https://${domain}/sitemap.xml`)\n }\n\n if (url.pathname === '/sitemap.xml') {\n return handleSitemap(request, siteConfig)\n }\n\n if (url.pathname.startsWith('/app') && url.pathname.endsWith('js')) {\n return handleAppJs(url, siteConfig)\n }\n\n if (url.pathname.startsWith('/api')) {\n return handleApi(url, request)\n }\n\n if (url.pathname.endsWith('.js')) {\n return handleJs(url)\n }\n\n if (url.pathname.endsWith('favicon.ico') && siteIcon) {\n return handleFavicon(url, siteIcon)\n }\n\n if (\n url.pathname.startsWith('/_assets') ||\n url.pathname.startsWith('/image') ||\n url.pathname.startsWith('/f/refresh') ||\n url.pathname.match(/\\.[a-zA-Z]{2,4}$/)\n ) {\n return handleNotionAsset(url)\n }\n\n // Handle slugs, from site-config and from KV\n const slugHash = url.pathname.split('/').pop().split('-').pop()\n const page = slugToPage[slugHash]\n\n if (page) {\n // console.log(`Redirecting ${slug} to https://${domain}/${page}`);\n\n return Response.redirect(`https://${domain}/${page}`, 301)\n } else if (slugHash.length !== 32 && !slugHash.match(/^[0-9a-f]+$/i)) {\n if (siteConfig.fof?.page?.length) {\n return Response.redirect(`https://${domain}/${siteConfig.fof.page}`, 301)\n } else {\n console.error('!! Page Not found (404)', url.pathname)\n\n return new Response('NoteHost: Page Not found (404).', { status: 404 })\n }\n }\n } else if (subDomain && siteConfig.subDomains) {\n const sub = siteConfig.subDomains[subDomain]\n\n if (sub) {\n // console.log(`Redirecting ${url.hostname} to ${sub.redirect}`)\n\n return Response.redirect(sub.redirect, 301)\n }\n }\n\n const response = await fetch(url.toString(), {\n body: request.body,\n headers: request.headers,\n method: request.method,\n })\n const ret = new Response(response.body as BodyInit, response)\n\n ret.headers.delete('Content-Security-Policy')\n ret.headers.delete('X-Content-Security-Policy')\n\n return cloudflare ? appendJavascript(ret, url, siteConfig) : appendJavascriptPolyfill(ret, url, siteConfig)\n}\n"],"mappings":"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","names":["siteConfig","siteConfig","siteConfig","siteConfig","siteConfig"]}
{"version":3,"sources":["../src/index.ts","../src/config-helpers.ts","../src/rewriters/_body-js-string.ts","../src/rewriters/body-rewriter.ts","../src/rewriters/head-rewriter.ts","../src/rewriters/meta-rewriter.ts","../src/append-js.ts","../src/append-js-pf.ts","../src/handlers/handle-favicon.ts","../src/handlers/handle-other.ts","../src/handlers/handle-api.ts","../src/handlers/handle-app-js.ts","../src/handlers/handle-js.ts","../src/handlers/handle-options.ts","../src/handlers/handle-sitemap.ts","../src/reverse-proxy-init.ts","../src/reverse-proxy.ts"],"sourcesContent":["export * from './config-helpers'\nexport * from './reverse-proxy'\nexport { initializeReverseProxy } from './reverse-proxy-init'\nexport * from './types'\n","export function googleTag(googleTagId: string) {\n return `\n <!-- Google tag (gtag.js) -->\n <script async src=\"https://www.googletagmanager.com/gtag/js?id=${googleTagId}\"></script>\n <script>\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n \n gtag('config', '${googleTagId}');\n </script>\n `\n}\n","export const BODY_JS_STRING = `\n/* eslint-disable no-unused-vars */\n/* eslint-disable prefer-rest-params */\n/* eslint-disable no-lonely-if */\n/* eslint-disable no-restricted-globals */\n/* eslint-disable no-underscore-dangle */\n/* eslint-disable no-undef */\nlocalStorage.__console = true\n\nconst el = document.createElement('div')\nlet redirected = false\n\nfunction getPage() {\n return location.pathname.slice(-32)\n}\n\nfunction getSlug() {\n return location.pathname.slice(1)\n}\n\nfunction updateSlug() {\n const slug = PAGE_TO_SLUG[getPage()]\n\n if (slug != null) {\n history.replaceState(history.state, '', ['/', slug].join(''))\n }\n}\n\nfunction enableConsoleEffectAndSetMode(mode) {\n if (__console && !__console.isEnabled) {\n __console.enable()\n window.location.reload()\n } else {\n __console?.environment?.ThemeStore?.setState({ mode })\n localStorage.setItem('newTheme', JSON.stringify({ mode }))\n }\n}\n\nfunction onDark() {\n el.innerHTML =\n '<div title=\"Change to Light Mode\" style=\"margin-left: 14px; margin-right: 14px; min-width: 0px;\"><div role=\"button\" tabindex=\"0\" style=\"user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;\"><div style=\"display: flex; flex-shrink: 0; height: 14px; width: 26px; padding: 2px; box-sizing: content-box; border-radius: 44px; border-style: solid; border-width: 0.1em; border-color: #D4D4D4; transition: background 200ms ease 0s, box-shadow 200ms ease 0s;\"><div style=\"width: 14px; height: 14px; border-radius: 44px; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(12px) translateY(0px); content: url(&quot;https://svgshare.com/i/12Tz.svg&quot;);\"></div></div></div></div>'\n document.body.classList.add('dark')\n enableConsoleEffectAndSetMode('dark')\n}\n\nfunction onLight() {\n el.innerHTML =\n '<div title=\"Change to Dark Mode\" style=\"margin-left: 14px; margin-right: 14px; min-width: 0px;\"><div role=\"button\" tabindex=\"0\" style=\"user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;\"><div style=\"display: flex; flex-shrink: 0; height: 14px; width: 26px; padding: 2px; box-sizing: content-box; border-radius: 44px; border-style: solid; border-width: 0.1em; border-color: #6D6C68; transition: background 200ms ease 0s, box-shadow 200ms ease 0s;\"><div style=\"width: 14px; height: 14px; border-radius: 44px; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(0px) translateY(0px); content: url(&quot;https://svgshare.com/i/12VG.svg&quot;);\"></div></div></div></div>'\n document.body.classList.remove('dark')\n enableConsoleEffectAndSetMode('light')\n}\n\nfunction toggle() {\n if (document.body.classList.contains('dark')) {\n onLight()\n } else {\n onDark()\n }\n}\n\nfunction addDarkModeButton(device) {\n const nav =\n device === 'web'\n ? document.querySelector('.notion-topbar').firstChild\n : document.querySelector('.notion-topbar-mobile')\n\n el.className = 'toggle-mode'\n el.addEventListener('click', toggle)\n\n const timeout = device === 'web' ? 0 : 500\n\n setTimeout(() => {\n nav.appendChild(el)\n }, timeout)\n\n // get the current theme and add the toggle to represent that theme\n const currentTheme = JSON.parse(localStorage.getItem('newTheme'))?.mode\n\n if (currentTheme) {\n if (currentTheme === 'dark') {\n onDark()\n } else {\n onLight()\n }\n } else {\n // enable smart dark mode based on user-preference\n if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n onDark()\n } else {\n onLight()\n }\n }\n\n // try to detect if user-preference change\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {\n toggle()\n })\n}\n\nconst observer = new MutationObserver(() => {\n if (redirected) return\n\n const nav = document.querySelector('.notion-topbar')\n const mobileNav = document.querySelector('.notion-topbar-mobile')\n\n if ((nav && nav.firstChild && nav.firstChild.firstChild) || (mobileNav && mobileNav.firstChild)) {\n // console.log('redirected', getSlug())\n updateSlug()\n redirected = true\n\n addDarkModeButton(nav ? 'web' : 'mobile')\n\n const { onpopstate } = window\n\n window.onpopstate = function () {\n // console.log('onpopstate');\n if (slugs.includes(getSlug())) {\n const page = SLUG_TO_PAGE[getSlug()]\n\n if (page) {\n // console.log('slug:', getSlug())\n // console.log('redirecting to:', page)\n history.replaceState(history.state, 'bypass', ['/', page].join(''))\n }\n }\n\n onpopstate.apply(this, [].slice.call(arguments))\n updateSlug()\n }\n }\n})\n\nobserver.observe(document.querySelector('#notion-app'), {\n childList: true,\n subtree: true,\n})\n\nconst { replaceState, back, forward } = window.history\n\nwindow.history.back = function () {\n back.apply(window.history, arguments)\n}\n\nwindow.history.forward = function () {\n forward.apply(window.history, arguments)\n}\n\nwindow.history.replaceState = function () {\n if (arguments[1] === 'bypass') {\n return\n }\n\n const slug = getSlug()\n const isKnownSlug = slugs.includes(slug)\n\n console.log('replaceState:', { slug, isKnownSlug, arguments })\n\n // console.log('replaceState arguments:', arguments)\n // console.log('replaceState state:', state)\n\n if (arguments[2] === '/login') {\n const page = SLUG_TO_PAGE[slug]\n\n if (page) {\n // console.log('slug:', slug)\n // console.log('redirecting to:', page)\n arguments[2] = ['/', page].join('')\n replaceState.apply(window.history, arguments)\n window.location.reload()\n\n return\n }\n } else {\n if (isKnownSlug && arguments[2] !== ['/', slug].join('')) {\n return\n }\n }\n\n replaceState.apply(window.history, arguments)\n}\n\nconst { pushState } = window.history\n\nwindow.history.pushState = function () {\n const dest = new URL(location.protocol + location.host + arguments[2])\n const id = dest.pathname.slice(-32)\n\n // console.log('pushState state:', state)\n // console.log('pushState id:', id)\n if (pages.includes(id)) {\n arguments[2] = ['/', PAGE_TO_SLUG[id]].join('')\n }\n\n return pushState.apply(window.history, arguments)\n}\n\nconst { open } = window.XMLHttpRequest.prototype\n\nwindow.XMLHttpRequest.prototype.open = function () {\n arguments[1] = arguments[1].replace(domain, notionDomain)\n\n if (arguments[1].indexOf('msgstore.' + notionDomain) > -1) {\n return\n }\n\n // console.log('XMLHttpRequest.open arguments:', arguments)\n open.apply(this, [].slice.call(arguments))\n}\n`\n","import { NoteHostSiteConfigFull } from '../types'\nimport { BODY_JS_STRING } from './_body-js-string'\n/* eslint-disable class-methods-use-this */\nexport class BodyRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n constructor(siteConfig: NoteHostSiteConfigFull) {\n this.siteConfig = siteConfig\n }\n\n element(element: Element) {\n const { domain, slugToPage, pageToSlug, slugs, pages, customBodyJS } = this.siteConfig\n\n element.append(\n `\n <script>\n const domain = '${domain}';\n window.CONFIG.domainBaseUrl = 'https://${domain}';\n const SLUG_TO_PAGE = ${JSON.stringify(slugToPage)};\n const PAGE_TO_SLUG = ${JSON.stringify(pageToSlug)};\n const slugs = ${JSON.stringify(slugs)};\n const pages = ${JSON.stringify(pages)};\n const notionDomain = '${this.siteConfig.notionDomain ? this.siteConfig.notionDomain : 'www.notion.so'}';\n ${BODY_JS_STRING}\n </script>\n ${customBodyJS ?? ''}\n `,\n {\n html: true,\n },\n )\n }\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\n/* eslint-disable class-methods-use-this */\nexport class HeadRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n constructor(siteConfig: NoteHostSiteConfigFull) {\n this.siteConfig = siteConfig\n }\n\n element(element: Element) {\n const { googleFont, customHeadJS, customHeadCSS } = this.siteConfig\n\n if (googleFont) {\n element.append(\n `<link href='https://fonts.googleapis.com/css?family=${googleFont.replace(\n ' ',\n '+',\n )}:Regular,Bold,Italic&display=swap' rel='stylesheet'>\n <style>* { font-family: \"${googleFont}\" !important; }</style>`,\n {\n html: true,\n },\n )\n }\n\n element.append(\n `<style>\n div.notion-topbar > div > div:nth-child(3) { display: none !important; }\n div.notion-topbar > div > div:nth-child(4) { display: none !important; }\n div.notion-topbar > div > div:nth-child(5) { display: none !important; }\n div.notion-topbar > div > div:nth-child(6) { display: none !important; }\n div.notion-topbar > div > div:nth-child(7) { display: none !important; }\n div.notion-topbar > div > div:nth-child(1n).toggle-mode { display: block !important; }\n \n div.notion-topbar-mobile > div:nth-child(3) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(4) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(7) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(1n).toggle-mode { display: block !important; }\n ${customHeadCSS ?? ''}\n </style>\n ${customHeadJS ?? ''}`,\n {\n html: true,\n },\n )\n }\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\n/* eslint-disable class-methods-use-this */\nexport class MetaRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n url: URL\n\n isRootPage: boolean\n\n constructor(siteConfig: NoteHostSiteConfigFull, url: URL) {\n this.siteConfig = siteConfig\n this.url = url\n this.isRootPage = this.siteConfig.pageToSlug[this.url.pathname.slice(1)] === ''\n }\n\n element(element: Element) {\n const { siteName, siteDescription, twitterHandle, siteImage, domain, pageToSlug, pageMetadata } = this.siteConfig\n const page = this.url.pathname.slice(-32)\n const property = element.getAttribute('property') ?? ''\n const name = element.getAttribute('name') ?? ''\n const content = element.getAttribute('content') ?? ''\n\n // console.log(\n // `${this.url}: <${element.tagName} name=\"${name}\" property=\"${property}\">${content}</${element.tagName}>`,\n // )\n\n if (element.tagName === 'title') {\n const pageTitle = pageMetadata[page]?.title ?? removeNotionAds(content)\n\n element.setInnerContent(pageTitle)\n }\n\n if (property === 'og:title' || name === 'twitter:title') {\n const pageTitle = pageMetadata[page]?.title ?? removeNotionAds(content)\n\n element.setAttribute('content', pageTitle)\n }\n\n if (property === 'og:site_name') {\n element.setAttribute('content', siteName)\n }\n\n if (name === 'article:author') {\n const pageAuthor = pageMetadata[page]?.author ?? content\n\n element.setAttribute('content', pageAuthor)\n }\n\n if (name === 'description' || property === 'og:description' || name === 'twitter:description') {\n if (this.isRootPage) {\n element.setAttribute('content', siteDescription)\n } else {\n const pageDescription = pageMetadata[page]?.description ?? removeNotionAds(content)\n\n element.setAttribute('content', pageDescription)\n }\n }\n\n if (property === 'og:url' || name === 'twitter:url') {\n if (this.isRootPage) {\n element.setAttribute('content', `https://${domain}/`)\n } else if (pageToSlug[page]) {\n element.setAttribute('content', `https://${domain}/${pageToSlug[page]}`)\n } else {\n element.setAttribute('content', `https://${domain}/${page}`)\n }\n }\n\n if (name === 'twitter:site') {\n if (twitterHandle) {\n element.setAttribute('content', `${twitterHandle}`)\n } else {\n element.remove()\n }\n }\n\n if (property === 'og:image' || name === 'twitter:image') {\n if (this.isRootPage && siteImage) {\n // console.log(`----- Image for url '${this.url.pathname}: ${siteImage}'`)\n element.setAttribute('content', siteImage)\n } else {\n const pageImage = pageMetadata[page]?.image ?? content\n // console.log(`----- Image for url '${this.url.pathname}: ${pageImage}'`)\n\n element.setAttribute('content', pageImage)\n }\n }\n\n if (name === 'apple-itunes-app') {\n element.remove()\n }\n }\n}\n\nfunction removeNotionAds(text: string) {\n return text\n .replace(' | Built with Notion', '')\n .replace(' | Notion', '')\n .replace('Built with Notion, the all-in-one connected workspace with publishing capabilities.', '')\n}\n","import { MetaRewriter, HeadRewriter, BodyRewriter } from './rewriters'\nimport { NoteHostSiteConfigFull } from './types'\n\nexport async function appendJavascript(res: Response, url: URL, config: NoteHostSiteConfigFull) {\n // eslint-disable-next-line no-undef\n return new HTMLRewriter()\n .on('title', new MetaRewriter(config, url))\n .on('meta', new MetaRewriter(config, url))\n .on('head', new HeadRewriter(config))\n .on('body', new BodyRewriter(config))\n .transform(res)\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { HTMLRewriter } from 'htmlrewriter'\nimport { NoteHostSiteConfigFull } from '.'\nimport { BodyRewriter, HeadRewriter, MetaRewriter } from './rewriters'\n\nexport async function appendJavascriptPolyfill(res: Response, url: URL, config: NoteHostSiteConfigFull) {\n // eslint-disable-next-line no-undef\n return new HTMLRewriter()\n .on('title', new MetaRewriter(config, url) as any)\n .on('meta', new MetaRewriter(config, url) as any)\n .on('head', new HeadRewriter(config) as any)\n .on('body', new BodyRewriter(config) as any)\n .transform(res)\n}\n","export async function handleFavicon(url: URL, siteIcon: string) {\n const response = await fetch(siteIcon)\n const body = await response.arrayBuffer()\n const ret = new Response(body, response)\n\n return ret\n}\n","export async function handleNotionAsset(url: URL) {\n const response = await fetch(url.toString())\n const body = await response.arrayBuffer()\n const ret = new Response(body, response)\n\n return ret\n}\n","/* eslint-disable no-undef */\nexport async function handleApi(url: URL, request: Request) {\n // Forward API\n const response = await fetch(url.toString(), {\n body: url.pathname.startsWith('/api/v3/getPublicPageData') ? null : request.body,\n headers: {\n 'content-type': 'application/json;charset=UTF-8',\n 'user-agent':\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',\n },\n method: 'POST',\n })\n const ret = new Response(response.body as BodyInit, response)\n\n ret.headers.set('Access-Control-Allow-Origin', '*')\n\n return ret\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\nexport async function handleAppJs(url: URL, siteConfig: NoteHostSiteConfigFull) {\n const { domain } = siteConfig\n const response = await fetch(url.toString())\n const body = await response.text()\n const siteRegex = new RegExp(\n siteConfig.notionDomain ? `${siteConfig.notionDomain}.notion.site` : 'www.notion.so',\n 'g',\n )\n const ret = new Response(body.replace(siteRegex, domain).replace(/notion.so/g, domain), response)\n\n ret.headers.set('Content-Type', 'application/x-javascript')\n\n return ret\n}\n","export async function handleJs(url: URL) {\n const response = await fetch(url.toString())\n const body = await response.text()\n const ret = new Response(body, response)\n\n ret.headers.set('Content-Type', 'application/x-javascript')\n\n return ret\n}\n","const corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n}\n\nexport function handleOptions(request: Request) {\n if (\n request.headers.get('Origin') !== null &&\n request.headers.get('Access-Control-Request-Method') !== null &&\n request.headers.get('Access-Control-Request-Headers') !== null\n ) {\n // Handle CORS pre-flight request.\n return new Response(null, {\n headers: corsHeaders,\n })\n }\n\n // Handle standard OPTIONS request.\n return new Response(null, {\n headers: {\n Allow: 'GET, HEAD, POST, PUT, OPTIONS',\n },\n })\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\nexport function handleSitemap(request: Request, siteConfig: NoteHostSiteConfigFull) {\n const { domain, slugs } = siteConfig\n let sitemap = '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">'\n\n slugs.forEach((slug) => {\n sitemap += `<url><loc>https://${domain}/${slug}</loc></url>`\n })\n sitemap += '</urlset>'\n\n const response = new Response(sitemap)\n\n response.headers.set('content-type', 'application/xml')\n\n return response\n}\n","import { NoteHostSiteConfig, NoteHostSiteConfigFull } from './types'\n\nexport let siteConfig: NoteHostSiteConfigFull = {} as NoteHostSiteConfigFull\n\nexport function initializeReverseProxy(siteConfigUser: NoteHostSiteConfig) {\n siteConfig = {\n ...siteConfigUser,\n slugs: [],\n pages: [],\n pageToSlug: {},\n }\n\n siteConfig.pageMetadata = siteConfig.pageMetadata || {}\n\n siteConfig.fof = {\n page: siteConfig.fof?.page,\n slug: siteConfig.fof?.slug || '404',\n }\n\n if (siteConfig.fof.page?.length) {\n siteConfig.slugToPage[siteConfig.fof.slug] = siteConfig.fof.page\n }\n\n // Build helper indexes for worker and for the client (body.js)\n Object.keys(siteConfig.slugToPage).forEach((slug) => {\n const pageId = siteConfig.slugToPage[slug]\n\n siteConfig.slugs.push(slug)\n siteConfig.pages.push(pageId)\n siteConfig.pageToSlug[pageId] = slug\n })\n}\n","/* eslint-disable no-undef */\nimport { appendJavascript } from './append-js'\nimport { appendJavascriptPolyfill } from './append-js-pf'\nimport { handleFavicon } from './handlers/handle-favicon'\nimport { handleNotionAsset } from './handlers/handle-other'\nimport { handleApi, handleAppJs, handleJs, handleOptions, handleSitemap } from './handlers/index'\nimport { siteConfig } from './reverse-proxy-init'\n\nexport async function reverseProxy(\n request: Request,\n opts: {\n cloudflare: boolean\n } = { cloudflare: true },\n) {\n const { cloudflare } = opts\n\n if (!siteConfig) {\n throw new Error('Site config is not initialized. Please call initializeReverseProxy() first.')\n }\n\n const { domain, slugToPage, siteIcon } = siteConfig\n\n if (request.method === 'OPTIONS') {\n return handleOptions(request)\n }\n\n const url = new URL(request.url)\n const subDomain = url.hostname.split('.')[0]\n\n if (url.hostname === domain) {\n url.hostname = siteConfig.notionDomain ? `${siteConfig.notionDomain}.notion.site` : 'www.notion.so'\n\n // Handle special Notion routes\n if (url.pathname === '/robots.txt') {\n return new Response(`Sitemap: https://${domain}/sitemap.xml`)\n }\n\n if (url.pathname === '/sitemap.xml') {\n return handleSitemap(request, siteConfig)\n }\n\n if (url.pathname.startsWith('/app') && url.pathname.endsWith('js')) {\n return handleAppJs(url, siteConfig)\n }\n\n if (url.pathname.startsWith('/api')) {\n return handleApi(url, request)\n }\n\n if (url.pathname.endsWith('.js')) {\n return handleJs(url)\n }\n\n if (url.pathname.endsWith('favicon.ico') && siteIcon) {\n return handleFavicon(url, siteIcon)\n }\n\n if (\n url.pathname.startsWith('/_assets') ||\n url.pathname.startsWith('/image') ||\n url.pathname.startsWith('/f/refresh') ||\n url.pathname.match(/\\.[a-zA-Z]{2,4}$/)\n ) {\n return handleNotionAsset(url)\n }\n\n // Handle slugs, from site-config and from KV\n console.log('url.pathname', url.pathname)\n\n const slug = url.pathname.split('/').pop()\n const slugHash = url.pathname.slice(-32)\n const page = slugToPage[slug]\n\n if (page) {\n console.log(`Redirecting ${slug} to https://${domain}/${page}`)\n\n return Response.redirect(`https://${domain}/${page}`, 301)\n } else if (slugHash && slugHash !== slug && slugHash.length === 32) {\n console.log(`Redirecting ${slug} to https://${domain}/${slugHash}`)\n\n return Response.redirect(`https://${domain}/${slugHash}`, 301)\n } else if (slug && slug.length !== 32) {\n if (siteConfig.fof?.page?.length) {\n return Response.redirect(`https://${domain}/${siteConfig.fof.page}`, 301)\n } else {\n console.error('!! Page Not found (404)', url.pathname)\n\n return new Response('NoteHost: Page Not found (404).', { status: 404 })\n }\n }\n } else if (subDomain && siteConfig.subDomains) {\n const sub = siteConfig.subDomains[subDomain]\n\n if (sub) {\n // console.log(`Redirecting ${url.hostname} to ${sub.redirect}`)\n\n return Response.redirect(sub.redirect, 301)\n }\n }\n\n const response = await fetch(url.toString(), {\n body: request.body,\n headers: request.headers,\n method: request.method,\n })\n const ret = new Response(response.body as BodyInit, response)\n\n ret.headers.delete('Content-Security-Policy')\n ret.headers.delete('X-Content-Security-Policy')\n\n return cloudflare ? appendJavascript(ret, url, siteConfig) : appendJavascriptPolyfill(ret, url, siteConfig)\n}\n"],"mappings":"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","names":["siteConfig","siteConfig","siteConfig","siteConfig","siteConfig"]}

@@ -124,4 +124,5 @@ // src/config-helpers.ts

// console.log('redirected', getSlug())
updateSlug()
redirected = true
updateSlug()
addDarkModeButton(nav ? 'web' : 'mobile')

@@ -154,4 +155,12 @@

const { replaceState } = window.history
const { replaceState, back, forward } = window.history
window.history.back = function () {
back.apply(window.history, arguments)
}
window.history.forward = function () {
forward.apply(window.history, arguments)
}
window.history.replaceState = function () {

@@ -162,8 +171,11 @@ if (arguments[1] === 'bypass') {

// console.log('replaceState arguments:', arguments)
// console.log('replaceState state:', state)
const slug = getSlug()
const isKnownSlug = slugs.includes(slug)
if (isKnownSlug && location.pathname !== ['/', slug].join('')) {
console.log('replaceState:', { slug, isKnownSlug, arguments })
// console.log('replaceState arguments:', arguments)
// console.log('replaceState state:', state)
if (arguments[2] === '/login') {
const page = SLUG_TO_PAGE[slug]

@@ -175,3 +187,11 @@

arguments[2] = ['/', page].join('')
replaceState.apply(window.history, arguments)
window.location.reload()
return
}
} else {
if (isKnownSlug && arguments[2] !== ['/', slug].join('')) {
return
}
}

@@ -512,7 +532,13 @@

}
const slugHash = url.pathname.split("/").pop().split("-").pop();
const page = slugToPage[slugHash];
console.log("url.pathname", url.pathname);
const slug = url.pathname.split("/").pop();
const slugHash = url.pathname.slice(-32);
const page = slugToPage[slug];
if (page) {
console.log(`Redirecting ${slug} to https://${domain}/${page}`);
return Response.redirect(`https://${domain}/${page}`, 301);
} else if (slugHash.length !== 32 && !slugHash.match(/^[0-9a-f]+$/i)) {
} else if (slugHash && slugHash !== slug && slugHash.length === 32) {
console.log(`Redirecting ${slug} to https://${domain}/${slugHash}`);
return Response.redirect(`https://${domain}/${slugHash}`, 301);
} else if (slug && slug.length !== 32) {
if (siteConfig.fof?.page?.length) {

@@ -519,0 +545,0 @@ return Response.redirect(`https://${domain}/${siteConfig.fof.page}`, 301);

@@ -1,1 +0,1 @@

{"version":3,"sources":["../src/config-helpers.ts","../src/rewriters/_body-js-string.ts","../src/rewriters/body-rewriter.ts","../src/rewriters/head-rewriter.ts","../src/rewriters/meta-rewriter.ts","../src/append-js.ts","../src/append-js-pf.ts","../src/handlers/handle-favicon.ts","../src/handlers/handle-other.ts","../src/handlers/handle-api.ts","../src/handlers/handle-app-js.ts","../src/handlers/handle-js.ts","../src/handlers/handle-options.ts","../src/handlers/handle-sitemap.ts","../src/reverse-proxy-init.ts","../src/reverse-proxy.ts"],"sourcesContent":["export function googleTag(googleTagId: string) {\n return `\n <!-- Google tag (gtag.js) -->\n <script async src=\"https://www.googletagmanager.com/gtag/js?id=${googleTagId}\"></script>\n <script>\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n \n gtag('config', '${googleTagId}');\n </script>\n `\n}\n","export const BODY_JS_STRING = `\n/* eslint-disable no-unused-vars */\n/* eslint-disable prefer-rest-params */\n/* eslint-disable no-lonely-if */\n/* eslint-disable no-restricted-globals */\n/* eslint-disable no-underscore-dangle */\n/* eslint-disable no-undef */\nlocalStorage.__console = true\n\nconst el = document.createElement('div')\nlet redirected = false\n\nfunction getPage() {\n return location.pathname.slice(-32)\n}\n\nfunction getSlug() {\n return location.pathname.slice(1)\n}\n\nfunction updateSlug() {\n const slug = PAGE_TO_SLUG[getPage()]\n\n if (slug != null) {\n history.replaceState(history.state, '', ['/', slug].join(''))\n }\n}\n\nfunction enableConsoleEffectAndSetMode(mode) {\n if (__console && !__console.isEnabled) {\n __console.enable()\n window.location.reload()\n } else {\n __console?.environment?.ThemeStore?.setState({ mode })\n localStorage.setItem('newTheme', JSON.stringify({ mode }))\n }\n}\n\nfunction onDark() {\n el.innerHTML =\n '<div title=\"Change to Light Mode\" style=\"margin-left: 14px; margin-right: 14px; min-width: 0px;\"><div role=\"button\" tabindex=\"0\" style=\"user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;\"><div style=\"display: flex; flex-shrink: 0; height: 14px; width: 26px; padding: 2px; box-sizing: content-box; border-radius: 44px; border-style: solid; border-width: 0.1em; border-color: #D4D4D4; transition: background 200ms ease 0s, box-shadow 200ms ease 0s;\"><div style=\"width: 14px; height: 14px; border-radius: 44px; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(12px) translateY(0px); content: url(&quot;https://svgshare.com/i/12Tz.svg&quot;);\"></div></div></div></div>'\n document.body.classList.add('dark')\n enableConsoleEffectAndSetMode('dark')\n}\n\nfunction onLight() {\n el.innerHTML =\n '<div title=\"Change to Dark Mode\" style=\"margin-left: 14px; margin-right: 14px; min-width: 0px;\"><div role=\"button\" tabindex=\"0\" style=\"user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;\"><div style=\"display: flex; flex-shrink: 0; height: 14px; width: 26px; padding: 2px; box-sizing: content-box; border-radius: 44px; border-style: solid; border-width: 0.1em; border-color: #6D6C68; transition: background 200ms ease 0s, box-shadow 200ms ease 0s;\"><div style=\"width: 14px; height: 14px; border-radius: 44px; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(0px) translateY(0px); content: url(&quot;https://svgshare.com/i/12VG.svg&quot;);\"></div></div></div></div>'\n document.body.classList.remove('dark')\n enableConsoleEffectAndSetMode('light')\n}\n\nfunction toggle() {\n if (document.body.classList.contains('dark')) {\n onLight()\n } else {\n onDark()\n }\n}\n\nfunction addDarkModeButton(device) {\n const nav =\n device === 'web'\n ? document.querySelector('.notion-topbar').firstChild\n : document.querySelector('.notion-topbar-mobile')\n\n el.className = 'toggle-mode'\n el.addEventListener('click', toggle)\n\n const timeout = device === 'web' ? 0 : 500\n\n setTimeout(() => {\n nav.appendChild(el)\n }, timeout)\n\n // get the current theme and add the toggle to represent that theme\n const currentTheme = JSON.parse(localStorage.getItem('newTheme'))?.mode\n\n if (currentTheme) {\n if (currentTheme === 'dark') {\n onDark()\n } else {\n onLight()\n }\n } else {\n // enable smart dark mode based on user-preference\n if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n onDark()\n } else {\n onLight()\n }\n }\n\n // try to detect if user-preference change\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {\n toggle()\n })\n}\n\nconst observer = new MutationObserver(() => {\n if (redirected) return\n\n const nav = document.querySelector('.notion-topbar')\n const mobileNav = document.querySelector('.notion-topbar-mobile')\n\n if ((nav && nav.firstChild && nav.firstChild.firstChild) || (mobileNav && mobileNav.firstChild)) {\n // console.log('redirected', getSlug())\n redirected = true\n updateSlug()\n addDarkModeButton(nav ? 'web' : 'mobile')\n\n const { onpopstate } = window\n\n window.onpopstate = function () {\n // console.log('onpopstate');\n if (slugs.includes(getSlug())) {\n const page = SLUG_TO_PAGE[getSlug()]\n\n if (page) {\n // console.log('slug:', getSlug())\n // console.log('redirecting to:', page)\n history.replaceState(history.state, 'bypass', ['/', page].join(''))\n }\n }\n\n onpopstate.apply(this, [].slice.call(arguments))\n updateSlug()\n }\n }\n})\n\nobserver.observe(document.querySelector('#notion-app'), {\n childList: true,\n subtree: true,\n})\n\nconst { replaceState } = window.history\n\nwindow.history.replaceState = function () {\n if (arguments[1] === 'bypass') {\n return\n }\n\n // console.log('replaceState arguments:', arguments)\n // console.log('replaceState state:', state)\n const slug = getSlug()\n const isKnownSlug = slugs.includes(slug)\n\n if (isKnownSlug && location.pathname !== ['/', slug].join('')) {\n const page = SLUG_TO_PAGE[slug]\n\n if (page) {\n // console.log('slug:', slug)\n // console.log('redirecting to:', page)\n arguments[2] = ['/', page].join('')\n }\n }\n\n replaceState.apply(window.history, arguments)\n}\n\nconst { pushState } = window.history\n\nwindow.history.pushState = function () {\n const dest = new URL(location.protocol + location.host + arguments[2])\n const id = dest.pathname.slice(-32)\n\n // console.log('pushState state:', state)\n // console.log('pushState id:', id)\n if (pages.includes(id)) {\n arguments[2] = ['/', PAGE_TO_SLUG[id]].join('')\n }\n\n return pushState.apply(window.history, arguments)\n}\n\nconst { open } = window.XMLHttpRequest.prototype\n\nwindow.XMLHttpRequest.prototype.open = function () {\n arguments[1] = arguments[1].replace(domain, notionDomain)\n\n if (arguments[1].indexOf('msgstore.' + notionDomain) > -1) {\n return\n }\n\n // console.log('XMLHttpRequest.open arguments:', arguments)\n open.apply(this, [].slice.call(arguments))\n}\n`\n","import { NoteHostSiteConfigFull } from '../types'\nimport { BODY_JS_STRING } from './_body-js-string'\n/* eslint-disable class-methods-use-this */\nexport class BodyRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n constructor(siteConfig: NoteHostSiteConfigFull) {\n this.siteConfig = siteConfig\n }\n\n element(element: Element) {\n const { domain, slugToPage, pageToSlug, slugs, pages, customBodyJS } = this.siteConfig\n\n element.append(\n `\n <script>\n const domain = '${domain}';\n window.CONFIG.domainBaseUrl = 'https://${domain}';\n const SLUG_TO_PAGE = ${JSON.stringify(slugToPage)};\n const PAGE_TO_SLUG = ${JSON.stringify(pageToSlug)};\n const slugs = ${JSON.stringify(slugs)};\n const pages = ${JSON.stringify(pages)};\n const notionDomain = '${this.siteConfig.notionDomain ? this.siteConfig.notionDomain : 'www.notion.so'}';\n ${BODY_JS_STRING}\n </script>\n ${customBodyJS ?? ''}\n `,\n {\n html: true,\n },\n )\n }\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\n/* eslint-disable class-methods-use-this */\nexport class HeadRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n constructor(siteConfig: NoteHostSiteConfigFull) {\n this.siteConfig = siteConfig\n }\n\n element(element: Element) {\n const { googleFont, customHeadJS, customHeadCSS } = this.siteConfig\n\n if (googleFont) {\n element.append(\n `<link href='https://fonts.googleapis.com/css?family=${googleFont.replace(\n ' ',\n '+',\n )}:Regular,Bold,Italic&display=swap' rel='stylesheet'>\n <style>* { font-family: \"${googleFont}\" !important; }</style>`,\n {\n html: true,\n },\n )\n }\n\n element.append(\n `<style>\n div.notion-topbar > div > div:nth-child(3) { display: none !important; }\n div.notion-topbar > div > div:nth-child(4) { display: none !important; }\n div.notion-topbar > div > div:nth-child(5) { display: none !important; }\n div.notion-topbar > div > div:nth-child(6) { display: none !important; }\n div.notion-topbar > div > div:nth-child(7) { display: none !important; }\n div.notion-topbar > div > div:nth-child(1n).toggle-mode { display: block !important; }\n \n div.notion-topbar-mobile > div:nth-child(3) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(4) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(7) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(1n).toggle-mode { display: block !important; }\n ${customHeadCSS ?? ''}\n </style>\n ${customHeadJS ?? ''}`,\n {\n html: true,\n },\n )\n }\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\n/* eslint-disable class-methods-use-this */\nexport class MetaRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n url: URL\n\n isRootPage: boolean\n\n constructor(siteConfig: NoteHostSiteConfigFull, url: URL) {\n this.siteConfig = siteConfig\n this.url = url\n this.isRootPage = this.siteConfig.pageToSlug[this.url.pathname.slice(1)] === ''\n }\n\n element(element: Element) {\n const { siteName, siteDescription, twitterHandle, siteImage, domain, pageToSlug, pageMetadata } = this.siteConfig\n const page = this.url.pathname.slice(-32)\n const property = element.getAttribute('property') ?? ''\n const name = element.getAttribute('name') ?? ''\n const content = element.getAttribute('content') ?? ''\n\n // console.log(\n // `${this.url}: <${element.tagName} name=\"${name}\" property=\"${property}\">${content}</${element.tagName}>`,\n // )\n\n if (element.tagName === 'title') {\n const pageTitle = pageMetadata[page]?.title ?? removeNotionAds(content)\n\n element.setInnerContent(pageTitle)\n }\n\n if (property === 'og:title' || name === 'twitter:title') {\n const pageTitle = pageMetadata[page]?.title ?? removeNotionAds(content)\n\n element.setAttribute('content', pageTitle)\n }\n\n if (property === 'og:site_name') {\n element.setAttribute('content', siteName)\n }\n\n if (name === 'article:author') {\n const pageAuthor = pageMetadata[page]?.author ?? content\n\n element.setAttribute('content', pageAuthor)\n }\n\n if (name === 'description' || property === 'og:description' || name === 'twitter:description') {\n if (this.isRootPage) {\n element.setAttribute('content', siteDescription)\n } else {\n const pageDescription = pageMetadata[page]?.description ?? removeNotionAds(content)\n\n element.setAttribute('content', pageDescription)\n }\n }\n\n if (property === 'og:url' || name === 'twitter:url') {\n if (this.isRootPage) {\n element.setAttribute('content', `https://${domain}/`)\n } else if (pageToSlug[page]) {\n element.setAttribute('content', `https://${domain}/${pageToSlug[page]}`)\n } else {\n element.setAttribute('content', `https://${domain}/${page}`)\n }\n }\n\n if (name === 'twitter:site') {\n if (twitterHandle) {\n element.setAttribute('content', `${twitterHandle}`)\n } else {\n element.remove()\n }\n }\n\n if (property === 'og:image' || name === 'twitter:image') {\n if (this.isRootPage && siteImage) {\n // console.log(`----- Image for url '${this.url.pathname}: ${siteImage}'`)\n element.setAttribute('content', siteImage)\n } else {\n const pageImage = pageMetadata[page]?.image ?? content\n // console.log(`----- Image for url '${this.url.pathname}: ${pageImage}'`)\n\n element.setAttribute('content', pageImage)\n }\n }\n\n if (name === 'apple-itunes-app') {\n element.remove()\n }\n }\n}\n\nfunction removeNotionAds(text: string) {\n return text\n .replace(' | Built with Notion', '')\n .replace(' | Notion', '')\n .replace('Built with Notion, the all-in-one connected workspace with publishing capabilities.', '')\n}\n","import { MetaRewriter, HeadRewriter, BodyRewriter } from './rewriters'\nimport { NoteHostSiteConfigFull } from './types'\n\nexport async function appendJavascript(res: Response, url: URL, config: NoteHostSiteConfigFull) {\n // eslint-disable-next-line no-undef\n return new HTMLRewriter()\n .on('title', new MetaRewriter(config, url))\n .on('meta', new MetaRewriter(config, url))\n .on('head', new HeadRewriter(config))\n .on('body', new BodyRewriter(config))\n .transform(res)\n}\n","import { HTMLRewriter } from 'htmlrewriter'\nimport { NoteHostSiteConfigFull } from '.'\nimport { BodyRewriter, HeadRewriter, MetaRewriter } from './rewriters'\n\nexport async function appendJavascriptPolyfill(res: Response, url: URL, config: NoteHostSiteConfigFull) {\n // eslint-disable-next-line no-undef\n return new HTMLRewriter()\n .on('title', new MetaRewriter(config, url) as any)\n .on('meta', new MetaRewriter(config, url) as any)\n .on('head', new HeadRewriter(config) as any)\n .on('body', new BodyRewriter(config) as any)\n .transform(res)\n}\n","export async function handleFavicon(url: URL, siteIcon: string) {\n const response = await fetch(siteIcon)\n const body = await response.arrayBuffer()\n const ret = new Response(body, response)\n\n return ret\n}\n","export async function handleNotionAsset(url: URL) {\n const response = await fetch(url.toString())\n const body = await response.arrayBuffer()\n const ret = new Response(body, response)\n\n return ret\n}\n","/* eslint-disable no-undef */\nexport async function handleApi(url: URL, request: Request) {\n // Forward API\n const response = await fetch(url.toString(), {\n body: url.pathname.startsWith('/api/v3/getPublicPageData') ? null : request.body,\n headers: {\n 'content-type': 'application/json;charset=UTF-8',\n 'user-agent':\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',\n },\n method: 'POST',\n })\n const ret = new Response(response.body as BodyInit, response)\n\n ret.headers.set('Access-Control-Allow-Origin', '*')\n\n return ret\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\nexport async function handleAppJs(url: URL, siteConfig: NoteHostSiteConfigFull) {\n const { domain } = siteConfig\n const response = await fetch(url.toString())\n const body = await response.text()\n const siteRegex = new RegExp(\n siteConfig.notionDomain ? `${siteConfig.notionDomain}.notion.site` : 'www.notion.so',\n 'g',\n )\n const ret = new Response(body.replace(siteRegex, domain).replace(/notion.so/g, domain), response)\n\n ret.headers.set('Content-Type', 'application/x-javascript')\n\n return ret\n}\n","export async function handleJs(url: URL) {\n const response = await fetch(url.toString())\n const body = await response.text()\n const ret = new Response(body, response)\n\n ret.headers.set('Content-Type', 'application/x-javascript')\n\n return ret\n}\n","const corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n}\n\nexport function handleOptions(request: Request) {\n if (\n request.headers.get('Origin') !== null &&\n request.headers.get('Access-Control-Request-Method') !== null &&\n request.headers.get('Access-Control-Request-Headers') !== null\n ) {\n // Handle CORS pre-flight request.\n return new Response(null, {\n headers: corsHeaders,\n })\n }\n\n // Handle standard OPTIONS request.\n return new Response(null, {\n headers: {\n Allow: 'GET, HEAD, POST, PUT, OPTIONS',\n },\n })\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\nexport function handleSitemap(request: Request, siteConfig: NoteHostSiteConfigFull) {\n const { domain, slugs } = siteConfig\n let sitemap = '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">'\n\n slugs.forEach((slug) => {\n sitemap += `<url><loc>https://${domain}/${slug}</loc></url>`\n })\n sitemap += '</urlset>'\n\n const response = new Response(sitemap)\n\n response.headers.set('content-type', 'application/xml')\n\n return response\n}\n","import { NoteHostSiteConfig, NoteHostSiteConfigFull } from './types'\n\nexport let siteConfig: NoteHostSiteConfigFull = {} as NoteHostSiteConfigFull\n\nexport function initializeReverseProxy(siteConfigUser: NoteHostSiteConfig) {\n siteConfig = {\n ...siteConfigUser,\n slugs: [],\n pages: [],\n pageToSlug: {},\n }\n\n siteConfig.pageMetadata = siteConfig.pageMetadata || {}\n\n siteConfig.fof = {\n page: siteConfig.fof?.page,\n slug: siteConfig.fof?.slug || '404',\n }\n\n if (siteConfig.fof.page?.length) {\n siteConfig.slugToPage[siteConfig.fof.slug] = siteConfig.fof.page\n }\n\n // Build helper indexes for worker and for the client (body.js)\n Object.keys(siteConfig.slugToPage).forEach((slug) => {\n const pageId = siteConfig.slugToPage[slug]\n\n siteConfig.slugs.push(slug)\n siteConfig.pages.push(pageId)\n siteConfig.pageToSlug[pageId] = slug\n })\n}\n","/* eslint-disable no-undef */\nimport { appendJavascript } from './append-js'\nimport { appendJavascriptPolyfill } from './append-js-pf'\nimport { handleFavicon } from './handlers/handle-favicon'\nimport { handleNotionAsset } from './handlers/handle-other'\nimport { handleApi, handleAppJs, handleJs, handleOptions, handleSitemap } from './handlers/index'\nimport { siteConfig } from './reverse-proxy-init'\n\nexport async function reverseProxy(\n request: Request,\n opts: {\n cloudflare: boolean\n } = { cloudflare: true },\n) {\n const { cloudflare } = opts\n\n if (!siteConfig) {\n throw new Error('Site config is not initialized. Please call initializeReverseProxy() first.')\n }\n\n const { domain, slugToPage, siteIcon } = siteConfig\n\n if (request.method === 'OPTIONS') {\n return handleOptions(request)\n }\n\n const url = new URL(request.url)\n const subDomain = url.hostname.split('.')[0]\n\n if (url.hostname === domain) {\n url.hostname = siteConfig.notionDomain ? `${siteConfig.notionDomain}.notion.site` : 'www.notion.so'\n\n // Handle special Notion routes\n if (url.pathname === '/robots.txt') {\n return new Response(`Sitemap: https://${domain}/sitemap.xml`)\n }\n\n if (url.pathname === '/sitemap.xml') {\n return handleSitemap(request, siteConfig)\n }\n\n if (url.pathname.startsWith('/app') && url.pathname.endsWith('js')) {\n return handleAppJs(url, siteConfig)\n }\n\n if (url.pathname.startsWith('/api')) {\n return handleApi(url, request)\n }\n\n if (url.pathname.endsWith('.js')) {\n return handleJs(url)\n }\n\n if (url.pathname.endsWith('favicon.ico') && siteIcon) {\n return handleFavicon(url, siteIcon)\n }\n\n if (\n url.pathname.startsWith('/_assets') ||\n url.pathname.startsWith('/image') ||\n url.pathname.startsWith('/f/refresh') ||\n url.pathname.match(/\\.[a-zA-Z]{2,4}$/)\n ) {\n return handleNotionAsset(url)\n }\n\n // Handle slugs, from site-config and from KV\n const slugHash = url.pathname.split('/').pop().split('-').pop()\n const page = slugToPage[slugHash]\n\n if (page) {\n // console.log(`Redirecting ${slug} to https://${domain}/${page}`);\n\n return Response.redirect(`https://${domain}/${page}`, 301)\n } else if (slugHash.length !== 32 && !slugHash.match(/^[0-9a-f]+$/i)) {\n if (siteConfig.fof?.page?.length) {\n return Response.redirect(`https://${domain}/${siteConfig.fof.page}`, 301)\n } else {\n console.error('!! Page Not found (404)', url.pathname)\n\n return new Response('NoteHost: Page Not found (404).', { status: 404 })\n }\n }\n } else if (subDomain && siteConfig.subDomains) {\n const sub = siteConfig.subDomains[subDomain]\n\n if (sub) {\n // console.log(`Redirecting ${url.hostname} to ${sub.redirect}`)\n\n return Response.redirect(sub.redirect, 301)\n }\n }\n\n const response = await fetch(url.toString(), {\n body: request.body,\n headers: request.headers,\n method: request.method,\n })\n const ret = new Response(response.body as BodyInit, response)\n\n ret.headers.delete('Content-Security-Policy')\n ret.headers.delete('X-Content-Security-Policy')\n\n return cloudflare ? appendJavascript(ret, url, siteConfig) : appendJavascriptPolyfill(ret, url, siteConfig)\n}\n"],"mappings":"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","names":["siteConfig","siteConfig","siteConfig","HTMLRewriter","HTMLRewriter","siteConfig","siteConfig"]}
{"version":3,"sources":["../src/config-helpers.ts","../src/rewriters/_body-js-string.ts","../src/rewriters/body-rewriter.ts","../src/rewriters/head-rewriter.ts","../src/rewriters/meta-rewriter.ts","../src/append-js.ts","../src/append-js-pf.ts","../src/handlers/handle-favicon.ts","../src/handlers/handle-other.ts","../src/handlers/handle-api.ts","../src/handlers/handle-app-js.ts","../src/handlers/handle-js.ts","../src/handlers/handle-options.ts","../src/handlers/handle-sitemap.ts","../src/reverse-proxy-init.ts","../src/reverse-proxy.ts"],"sourcesContent":["export function googleTag(googleTagId: string) {\n return `\n <!-- Google tag (gtag.js) -->\n <script async src=\"https://www.googletagmanager.com/gtag/js?id=${googleTagId}\"></script>\n <script>\n window.dataLayer = window.dataLayer || [];\n function gtag(){dataLayer.push(arguments);}\n gtag('js', new Date());\n \n gtag('config', '${googleTagId}');\n </script>\n `\n}\n","export const BODY_JS_STRING = `\n/* eslint-disable no-unused-vars */\n/* eslint-disable prefer-rest-params */\n/* eslint-disable no-lonely-if */\n/* eslint-disable no-restricted-globals */\n/* eslint-disable no-underscore-dangle */\n/* eslint-disable no-undef */\nlocalStorage.__console = true\n\nconst el = document.createElement('div')\nlet redirected = false\n\nfunction getPage() {\n return location.pathname.slice(-32)\n}\n\nfunction getSlug() {\n return location.pathname.slice(1)\n}\n\nfunction updateSlug() {\n const slug = PAGE_TO_SLUG[getPage()]\n\n if (slug != null) {\n history.replaceState(history.state, '', ['/', slug].join(''))\n }\n}\n\nfunction enableConsoleEffectAndSetMode(mode) {\n if (__console && !__console.isEnabled) {\n __console.enable()\n window.location.reload()\n } else {\n __console?.environment?.ThemeStore?.setState({ mode })\n localStorage.setItem('newTheme', JSON.stringify({ mode }))\n }\n}\n\nfunction onDark() {\n el.innerHTML =\n '<div title=\"Change to Light Mode\" style=\"margin-left: 14px; margin-right: 14px; min-width: 0px;\"><div role=\"button\" tabindex=\"0\" style=\"user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;\"><div style=\"display: flex; flex-shrink: 0; height: 14px; width: 26px; padding: 2px; box-sizing: content-box; border-radius: 44px; border-style: solid; border-width: 0.1em; border-color: #D4D4D4; transition: background 200ms ease 0s, box-shadow 200ms ease 0s;\"><div style=\"width: 14px; height: 14px; border-radius: 44px; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(12px) translateY(0px); content: url(&quot;https://svgshare.com/i/12Tz.svg&quot;);\"></div></div></div></div>'\n document.body.classList.add('dark')\n enableConsoleEffectAndSetMode('dark')\n}\n\nfunction onLight() {\n el.innerHTML =\n '<div title=\"Change to Dark Mode\" style=\"margin-left: 14px; margin-right: 14px; min-width: 0px;\"><div role=\"button\" tabindex=\"0\" style=\"user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;\"><div style=\"display: flex; flex-shrink: 0; height: 14px; width: 26px; padding: 2px; box-sizing: content-box; border-radius: 44px; border-style: solid; border-width: 0.1em; border-color: #6D6C68; transition: background 200ms ease 0s, box-shadow 200ms ease 0s;\"><div style=\"width: 14px; height: 14px; border-radius: 44px; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(0px) translateY(0px); content: url(&quot;https://svgshare.com/i/12VG.svg&quot;);\"></div></div></div></div>'\n document.body.classList.remove('dark')\n enableConsoleEffectAndSetMode('light')\n}\n\nfunction toggle() {\n if (document.body.classList.contains('dark')) {\n onLight()\n } else {\n onDark()\n }\n}\n\nfunction addDarkModeButton(device) {\n const nav =\n device === 'web'\n ? document.querySelector('.notion-topbar').firstChild\n : document.querySelector('.notion-topbar-mobile')\n\n el.className = 'toggle-mode'\n el.addEventListener('click', toggle)\n\n const timeout = device === 'web' ? 0 : 500\n\n setTimeout(() => {\n nav.appendChild(el)\n }, timeout)\n\n // get the current theme and add the toggle to represent that theme\n const currentTheme = JSON.parse(localStorage.getItem('newTheme'))?.mode\n\n if (currentTheme) {\n if (currentTheme === 'dark') {\n onDark()\n } else {\n onLight()\n }\n } else {\n // enable smart dark mode based on user-preference\n if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n onDark()\n } else {\n onLight()\n }\n }\n\n // try to detect if user-preference change\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {\n toggle()\n })\n}\n\nconst observer = new MutationObserver(() => {\n if (redirected) return\n\n const nav = document.querySelector('.notion-topbar')\n const mobileNav = document.querySelector('.notion-topbar-mobile')\n\n if ((nav && nav.firstChild && nav.firstChild.firstChild) || (mobileNav && mobileNav.firstChild)) {\n // console.log('redirected', getSlug())\n updateSlug()\n redirected = true\n\n addDarkModeButton(nav ? 'web' : 'mobile')\n\n const { onpopstate } = window\n\n window.onpopstate = function () {\n // console.log('onpopstate');\n if (slugs.includes(getSlug())) {\n const page = SLUG_TO_PAGE[getSlug()]\n\n if (page) {\n // console.log('slug:', getSlug())\n // console.log('redirecting to:', page)\n history.replaceState(history.state, 'bypass', ['/', page].join(''))\n }\n }\n\n onpopstate.apply(this, [].slice.call(arguments))\n updateSlug()\n }\n }\n})\n\nobserver.observe(document.querySelector('#notion-app'), {\n childList: true,\n subtree: true,\n})\n\nconst { replaceState, back, forward } = window.history\n\nwindow.history.back = function () {\n back.apply(window.history, arguments)\n}\n\nwindow.history.forward = function () {\n forward.apply(window.history, arguments)\n}\n\nwindow.history.replaceState = function () {\n if (arguments[1] === 'bypass') {\n return\n }\n\n const slug = getSlug()\n const isKnownSlug = slugs.includes(slug)\n\n console.log('replaceState:', { slug, isKnownSlug, arguments })\n\n // console.log('replaceState arguments:', arguments)\n // console.log('replaceState state:', state)\n\n if (arguments[2] === '/login') {\n const page = SLUG_TO_PAGE[slug]\n\n if (page) {\n // console.log('slug:', slug)\n // console.log('redirecting to:', page)\n arguments[2] = ['/', page].join('')\n replaceState.apply(window.history, arguments)\n window.location.reload()\n\n return\n }\n } else {\n if (isKnownSlug && arguments[2] !== ['/', slug].join('')) {\n return\n }\n }\n\n replaceState.apply(window.history, arguments)\n}\n\nconst { pushState } = window.history\n\nwindow.history.pushState = function () {\n const dest = new URL(location.protocol + location.host + arguments[2])\n const id = dest.pathname.slice(-32)\n\n // console.log('pushState state:', state)\n // console.log('pushState id:', id)\n if (pages.includes(id)) {\n arguments[2] = ['/', PAGE_TO_SLUG[id]].join('')\n }\n\n return pushState.apply(window.history, arguments)\n}\n\nconst { open } = window.XMLHttpRequest.prototype\n\nwindow.XMLHttpRequest.prototype.open = function () {\n arguments[1] = arguments[1].replace(domain, notionDomain)\n\n if (arguments[1].indexOf('msgstore.' + notionDomain) > -1) {\n return\n }\n\n // console.log('XMLHttpRequest.open arguments:', arguments)\n open.apply(this, [].slice.call(arguments))\n}\n`\n","import { NoteHostSiteConfigFull } from '../types'\nimport { BODY_JS_STRING } from './_body-js-string'\n/* eslint-disable class-methods-use-this */\nexport class BodyRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n constructor(siteConfig: NoteHostSiteConfigFull) {\n this.siteConfig = siteConfig\n }\n\n element(element: Element) {\n const { domain, slugToPage, pageToSlug, slugs, pages, customBodyJS } = this.siteConfig\n\n element.append(\n `\n <script>\n const domain = '${domain}';\n window.CONFIG.domainBaseUrl = 'https://${domain}';\n const SLUG_TO_PAGE = ${JSON.stringify(slugToPage)};\n const PAGE_TO_SLUG = ${JSON.stringify(pageToSlug)};\n const slugs = ${JSON.stringify(slugs)};\n const pages = ${JSON.stringify(pages)};\n const notionDomain = '${this.siteConfig.notionDomain ? this.siteConfig.notionDomain : 'www.notion.so'}';\n ${BODY_JS_STRING}\n </script>\n ${customBodyJS ?? ''}\n `,\n {\n html: true,\n },\n )\n }\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\n/* eslint-disable class-methods-use-this */\nexport class HeadRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n constructor(siteConfig: NoteHostSiteConfigFull) {\n this.siteConfig = siteConfig\n }\n\n element(element: Element) {\n const { googleFont, customHeadJS, customHeadCSS } = this.siteConfig\n\n if (googleFont) {\n element.append(\n `<link href='https://fonts.googleapis.com/css?family=${googleFont.replace(\n ' ',\n '+',\n )}:Regular,Bold,Italic&display=swap' rel='stylesheet'>\n <style>* { font-family: \"${googleFont}\" !important; }</style>`,\n {\n html: true,\n },\n )\n }\n\n element.append(\n `<style>\n div.notion-topbar > div > div:nth-child(3) { display: none !important; }\n div.notion-topbar > div > div:nth-child(4) { display: none !important; }\n div.notion-topbar > div > div:nth-child(5) { display: none !important; }\n div.notion-topbar > div > div:nth-child(6) { display: none !important; }\n div.notion-topbar > div > div:nth-child(7) { display: none !important; }\n div.notion-topbar > div > div:nth-child(1n).toggle-mode { display: block !important; }\n \n div.notion-topbar-mobile > div:nth-child(3) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(4) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(7) { display: none !important; }\n div.notion-topbar-mobile > div:nth-child(1n).toggle-mode { display: block !important; }\n ${customHeadCSS ?? ''}\n </style>\n ${customHeadJS ?? ''}`,\n {\n html: true,\n },\n )\n }\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\n/* eslint-disable class-methods-use-this */\nexport class MetaRewriter {\n siteConfig: NoteHostSiteConfigFull\n\n url: URL\n\n isRootPage: boolean\n\n constructor(siteConfig: NoteHostSiteConfigFull, url: URL) {\n this.siteConfig = siteConfig\n this.url = url\n this.isRootPage = this.siteConfig.pageToSlug[this.url.pathname.slice(1)] === ''\n }\n\n element(element: Element) {\n const { siteName, siteDescription, twitterHandle, siteImage, domain, pageToSlug, pageMetadata } = this.siteConfig\n const page = this.url.pathname.slice(-32)\n const property = element.getAttribute('property') ?? ''\n const name = element.getAttribute('name') ?? ''\n const content = element.getAttribute('content') ?? ''\n\n // console.log(\n // `${this.url}: <${element.tagName} name=\"${name}\" property=\"${property}\">${content}</${element.tagName}>`,\n // )\n\n if (element.tagName === 'title') {\n const pageTitle = pageMetadata[page]?.title ?? removeNotionAds(content)\n\n element.setInnerContent(pageTitle)\n }\n\n if (property === 'og:title' || name === 'twitter:title') {\n const pageTitle = pageMetadata[page]?.title ?? removeNotionAds(content)\n\n element.setAttribute('content', pageTitle)\n }\n\n if (property === 'og:site_name') {\n element.setAttribute('content', siteName)\n }\n\n if (name === 'article:author') {\n const pageAuthor = pageMetadata[page]?.author ?? content\n\n element.setAttribute('content', pageAuthor)\n }\n\n if (name === 'description' || property === 'og:description' || name === 'twitter:description') {\n if (this.isRootPage) {\n element.setAttribute('content', siteDescription)\n } else {\n const pageDescription = pageMetadata[page]?.description ?? removeNotionAds(content)\n\n element.setAttribute('content', pageDescription)\n }\n }\n\n if (property === 'og:url' || name === 'twitter:url') {\n if (this.isRootPage) {\n element.setAttribute('content', `https://${domain}/`)\n } else if (pageToSlug[page]) {\n element.setAttribute('content', `https://${domain}/${pageToSlug[page]}`)\n } else {\n element.setAttribute('content', `https://${domain}/${page}`)\n }\n }\n\n if (name === 'twitter:site') {\n if (twitterHandle) {\n element.setAttribute('content', `${twitterHandle}`)\n } else {\n element.remove()\n }\n }\n\n if (property === 'og:image' || name === 'twitter:image') {\n if (this.isRootPage && siteImage) {\n // console.log(`----- Image for url '${this.url.pathname}: ${siteImage}'`)\n element.setAttribute('content', siteImage)\n } else {\n const pageImage = pageMetadata[page]?.image ?? content\n // console.log(`----- Image for url '${this.url.pathname}: ${pageImage}'`)\n\n element.setAttribute('content', pageImage)\n }\n }\n\n if (name === 'apple-itunes-app') {\n element.remove()\n }\n }\n}\n\nfunction removeNotionAds(text: string) {\n return text\n .replace(' | Built with Notion', '')\n .replace(' | Notion', '')\n .replace('Built with Notion, the all-in-one connected workspace with publishing capabilities.', '')\n}\n","import { MetaRewriter, HeadRewriter, BodyRewriter } from './rewriters'\nimport { NoteHostSiteConfigFull } from './types'\n\nexport async function appendJavascript(res: Response, url: URL, config: NoteHostSiteConfigFull) {\n // eslint-disable-next-line no-undef\n return new HTMLRewriter()\n .on('title', new MetaRewriter(config, url))\n .on('meta', new MetaRewriter(config, url))\n .on('head', new HeadRewriter(config))\n .on('body', new BodyRewriter(config))\n .transform(res)\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { HTMLRewriter } from 'htmlrewriter'\nimport { NoteHostSiteConfigFull } from '.'\nimport { BodyRewriter, HeadRewriter, MetaRewriter } from './rewriters'\n\nexport async function appendJavascriptPolyfill(res: Response, url: URL, config: NoteHostSiteConfigFull) {\n // eslint-disable-next-line no-undef\n return new HTMLRewriter()\n .on('title', new MetaRewriter(config, url) as any)\n .on('meta', new MetaRewriter(config, url) as any)\n .on('head', new HeadRewriter(config) as any)\n .on('body', new BodyRewriter(config) as any)\n .transform(res)\n}\n","export async function handleFavicon(url: URL, siteIcon: string) {\n const response = await fetch(siteIcon)\n const body = await response.arrayBuffer()\n const ret = new Response(body, response)\n\n return ret\n}\n","export async function handleNotionAsset(url: URL) {\n const response = await fetch(url.toString())\n const body = await response.arrayBuffer()\n const ret = new Response(body, response)\n\n return ret\n}\n","/* eslint-disable no-undef */\nexport async function handleApi(url: URL, request: Request) {\n // Forward API\n const response = await fetch(url.toString(), {\n body: url.pathname.startsWith('/api/v3/getPublicPageData') ? null : request.body,\n headers: {\n 'content-type': 'application/json;charset=UTF-8',\n 'user-agent':\n 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36',\n },\n method: 'POST',\n })\n const ret = new Response(response.body as BodyInit, response)\n\n ret.headers.set('Access-Control-Allow-Origin', '*')\n\n return ret\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\nexport async function handleAppJs(url: URL, siteConfig: NoteHostSiteConfigFull) {\n const { domain } = siteConfig\n const response = await fetch(url.toString())\n const body = await response.text()\n const siteRegex = new RegExp(\n siteConfig.notionDomain ? `${siteConfig.notionDomain}.notion.site` : 'www.notion.so',\n 'g',\n )\n const ret = new Response(body.replace(siteRegex, domain).replace(/notion.so/g, domain), response)\n\n ret.headers.set('Content-Type', 'application/x-javascript')\n\n return ret\n}\n","export async function handleJs(url: URL) {\n const response = await fetch(url.toString())\n const body = await response.text()\n const ret = new Response(body, response)\n\n ret.headers.set('Content-Type', 'application/x-javascript')\n\n return ret\n}\n","const corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, HEAD, POST, PUT, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n}\n\nexport function handleOptions(request: Request) {\n if (\n request.headers.get('Origin') !== null &&\n request.headers.get('Access-Control-Request-Method') !== null &&\n request.headers.get('Access-Control-Request-Headers') !== null\n ) {\n // Handle CORS pre-flight request.\n return new Response(null, {\n headers: corsHeaders,\n })\n }\n\n // Handle standard OPTIONS request.\n return new Response(null, {\n headers: {\n Allow: 'GET, HEAD, POST, PUT, OPTIONS',\n },\n })\n}\n","import { NoteHostSiteConfigFull } from '../types'\n\nexport function handleSitemap(request: Request, siteConfig: NoteHostSiteConfigFull) {\n const { domain, slugs } = siteConfig\n let sitemap = '<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">'\n\n slugs.forEach((slug) => {\n sitemap += `<url><loc>https://${domain}/${slug}</loc></url>`\n })\n sitemap += '</urlset>'\n\n const response = new Response(sitemap)\n\n response.headers.set('content-type', 'application/xml')\n\n return response\n}\n","import { NoteHostSiteConfig, NoteHostSiteConfigFull } from './types'\n\nexport let siteConfig: NoteHostSiteConfigFull = {} as NoteHostSiteConfigFull\n\nexport function initializeReverseProxy(siteConfigUser: NoteHostSiteConfig) {\n siteConfig = {\n ...siteConfigUser,\n slugs: [],\n pages: [],\n pageToSlug: {},\n }\n\n siteConfig.pageMetadata = siteConfig.pageMetadata || {}\n\n siteConfig.fof = {\n page: siteConfig.fof?.page,\n slug: siteConfig.fof?.slug || '404',\n }\n\n if (siteConfig.fof.page?.length) {\n siteConfig.slugToPage[siteConfig.fof.slug] = siteConfig.fof.page\n }\n\n // Build helper indexes for worker and for the client (body.js)\n Object.keys(siteConfig.slugToPage).forEach((slug) => {\n const pageId = siteConfig.slugToPage[slug]\n\n siteConfig.slugs.push(slug)\n siteConfig.pages.push(pageId)\n siteConfig.pageToSlug[pageId] = slug\n })\n}\n","/* eslint-disable no-undef */\nimport { appendJavascript } from './append-js'\nimport { appendJavascriptPolyfill } from './append-js-pf'\nimport { handleFavicon } from './handlers/handle-favicon'\nimport { handleNotionAsset } from './handlers/handle-other'\nimport { handleApi, handleAppJs, handleJs, handleOptions, handleSitemap } from './handlers/index'\nimport { siteConfig } from './reverse-proxy-init'\n\nexport async function reverseProxy(\n request: Request,\n opts: {\n cloudflare: boolean\n } = { cloudflare: true },\n) {\n const { cloudflare } = opts\n\n if (!siteConfig) {\n throw new Error('Site config is not initialized. Please call initializeReverseProxy() first.')\n }\n\n const { domain, slugToPage, siteIcon } = siteConfig\n\n if (request.method === 'OPTIONS') {\n return handleOptions(request)\n }\n\n const url = new URL(request.url)\n const subDomain = url.hostname.split('.')[0]\n\n if (url.hostname === domain) {\n url.hostname = siteConfig.notionDomain ? `${siteConfig.notionDomain}.notion.site` : 'www.notion.so'\n\n // Handle special Notion routes\n if (url.pathname === '/robots.txt') {\n return new Response(`Sitemap: https://${domain}/sitemap.xml`)\n }\n\n if (url.pathname === '/sitemap.xml') {\n return handleSitemap(request, siteConfig)\n }\n\n if (url.pathname.startsWith('/app') && url.pathname.endsWith('js')) {\n return handleAppJs(url, siteConfig)\n }\n\n if (url.pathname.startsWith('/api')) {\n return handleApi(url, request)\n }\n\n if (url.pathname.endsWith('.js')) {\n return handleJs(url)\n }\n\n if (url.pathname.endsWith('favicon.ico') && siteIcon) {\n return handleFavicon(url, siteIcon)\n }\n\n if (\n url.pathname.startsWith('/_assets') ||\n url.pathname.startsWith('/image') ||\n url.pathname.startsWith('/f/refresh') ||\n url.pathname.match(/\\.[a-zA-Z]{2,4}$/)\n ) {\n return handleNotionAsset(url)\n }\n\n // Handle slugs, from site-config and from KV\n console.log('url.pathname', url.pathname)\n\n const slug = url.pathname.split('/').pop()\n const slugHash = url.pathname.slice(-32)\n const page = slugToPage[slug]\n\n if (page) {\n console.log(`Redirecting ${slug} to https://${domain}/${page}`)\n\n return Response.redirect(`https://${domain}/${page}`, 301)\n } else if (slugHash && slugHash !== slug && slugHash.length === 32) {\n console.log(`Redirecting ${slug} to https://${domain}/${slugHash}`)\n\n return Response.redirect(`https://${domain}/${slugHash}`, 301)\n } else if (slug && slug.length !== 32) {\n if (siteConfig.fof?.page?.length) {\n return Response.redirect(`https://${domain}/${siteConfig.fof.page}`, 301)\n } else {\n console.error('!! Page Not found (404)', url.pathname)\n\n return new Response('NoteHost: Page Not found (404).', { status: 404 })\n }\n }\n } else if (subDomain && siteConfig.subDomains) {\n const sub = siteConfig.subDomains[subDomain]\n\n if (sub) {\n // console.log(`Redirecting ${url.hostname} to ${sub.redirect}`)\n\n return Response.redirect(sub.redirect, 301)\n }\n }\n\n const response = await fetch(url.toString(), {\n body: request.body,\n headers: request.headers,\n method: request.method,\n })\n const ret = new Response(response.body as BodyInit, response)\n\n ret.headers.delete('Content-Security-Policy')\n ret.headers.delete('X-Content-Security-Policy')\n\n return cloudflare ? appendJavascript(ret, url, siteConfig) : appendJavascriptPolyfill(ret, url, siteConfig)\n}\n"],"mappings":";AAAO,SAAS,UAAU,aAAqB;AAC7C,SAAO;AAAA;AAAA,mEAE0D,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAMxD,WAAW;AAAA;AAAA;AAGjC;;;ACZO,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGvB,IAAM,eAAN,MAAmB;AAAA,EACxB;AAAA,EAEA,YAAYA,aAAoC;AAC9C,SAAK,aAAaA;AAAA,EACpB;AAAA,EAEA,QAAQ,SAAkB;AACxB,UAAM,EAAE,QAAQ,YAAY,YAAY,OAAO,OAAO,aAAa,IAAI,KAAK;AAE5E,YAAQ;AAAA,MACN;AAAA;AAAA,wBAEkB,MAAM;AAAA,+CACiB,MAAM;AAAA,6BACxB,KAAK,UAAU,UAAU,CAAC;AAAA,6BAC1B,KAAK,UAAU,UAAU,CAAC;AAAA,sBACjC,KAAK,UAAU,KAAK,CAAC;AAAA,sBACrB,KAAK,UAAU,KAAK,CAAC;AAAA,8BACb,KAAK,WAAW,eAAe,KAAK,WAAW,eAAe,eAAe;AAAA,QACnG,cAAc;AAAA;AAAA,QAEd,gBAAgB,EAAE;AAAA;AAAA,MAEpB;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;;;AC7BO,IAAM,eAAN,MAAmB;AAAA,EACxB;AAAA,EAEA,YAAYC,aAAoC;AAC9C,SAAK,aAAaA;AAAA,EACpB;AAAA,EAEA,QAAQ,SAAkB;AACxB,UAAM,EAAE,YAAY,cAAc,cAAc,IAAI,KAAK;AAEzD,QAAI,YAAY;AACd,cAAQ;AAAA,QACN,uDAAuD,WAAW;AAAA,UAChE;AAAA,UACA;AAAA,QACF,CAAC;AAAA,qCAC4B,UAAU;AAAA,QACvC;AAAA,UACE,MAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,YAAQ;AAAA,MACN;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAYI,iBAAiB,EAAE;AAAA;AAAA,UAEnB,gBAAgB,EAAE;AAAA,MACtB;AAAA,QACE,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;;;AC5CO,IAAM,eAAN,MAAmB;AAAA,EACxB;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA,YAAYC,aAAoC,KAAU;AACxD,SAAK,aAAaA;AAClB,SAAK,MAAM;AACX,SAAK,aAAa,KAAK,WAAW,WAAW,KAAK,IAAI,SAAS,MAAM,CAAC,CAAC,MAAM;AAAA,EAC/E;AAAA,EAEA,QAAQ,SAAkB;AACxB,UAAM,EAAE,UAAU,iBAAiB,eAAe,WAAW,QAAQ,YAAY,aAAa,IAAI,KAAK;AACvG,UAAM,OAAO,KAAK,IAAI,SAAS,MAAM,GAAG;AACxC,UAAM,WAAW,QAAQ,aAAa,UAAU,KAAK;AACrD,UAAM,OAAO,QAAQ,aAAa,MAAM,KAAK;AAC7C,UAAM,UAAU,QAAQ,aAAa,SAAS,KAAK;AAMnD,QAAI,QAAQ,YAAY,SAAS;AAC/B,YAAM,YAAY,aAAa,IAAI,GAAG,SAAS,gBAAgB,OAAO;AAEtE,cAAQ,gBAAgB,SAAS;AAAA,IACnC;AAEA,QAAI,aAAa,cAAc,SAAS,iBAAiB;AACvD,YAAM,YAAY,aAAa,IAAI,GAAG,SAAS,gBAAgB,OAAO;AAEtE,cAAQ,aAAa,WAAW,SAAS;AAAA,IAC3C;AAEA,QAAI,aAAa,gBAAgB;AAC/B,cAAQ,aAAa,WAAW,QAAQ;AAAA,IAC1C;AAEA,QAAI,SAAS,kBAAkB;AAC7B,YAAM,aAAa,aAAa,IAAI,GAAG,UAAU;AAEjD,cAAQ,aAAa,WAAW,UAAU;AAAA,IAC5C;AAEA,QAAI,SAAS,iBAAiB,aAAa,oBAAoB,SAAS,uBAAuB;AAC7F,UAAI,KAAK,YAAY;AACnB,gBAAQ,aAAa,WAAW,eAAe;AAAA,MACjD,OAAO;AACL,cAAM,kBAAkB,aAAa,IAAI,GAAG,eAAe,gBAAgB,OAAO;AAElF,gBAAQ,aAAa,WAAW,eAAe;AAAA,MACjD;AAAA,IACF;AAEA,QAAI,aAAa,YAAY,SAAS,eAAe;AACnD,UAAI,KAAK,YAAY;AACnB,gBAAQ,aAAa,WAAW,WAAW,MAAM,GAAG;AAAA,MACtD,WAAW,WAAW,IAAI,GAAG;AAC3B,gBAAQ,aAAa,WAAW,WAAW,MAAM,IAAI,WAAW,IAAI,CAAC,EAAE;AAAA,MACzE,OAAO;AACL,gBAAQ,aAAa,WAAW,WAAW,MAAM,IAAI,IAAI,EAAE;AAAA,MAC7D;AAAA,IACF;AAEA,QAAI,SAAS,gBAAgB;AAC3B,UAAI,eAAe;AACjB,gBAAQ,aAAa,WAAW,GAAG,aAAa,EAAE;AAAA,MACpD,OAAO;AACL,gBAAQ,OAAO;AAAA,MACjB;AAAA,IACF;AAEA,QAAI,aAAa,cAAc,SAAS,iBAAiB;AACvD,UAAI,KAAK,cAAc,WAAW;AAEhC,gBAAQ,aAAa,WAAW,SAAS;AAAA,MAC3C,OAAO;AACL,cAAM,YAAY,aAAa,IAAI,GAAG,SAAS;AAG/C,gBAAQ,aAAa,WAAW,SAAS;AAAA,MAC3C;AAAA,IACF;AAEA,QAAI,SAAS,oBAAoB;AAC/B,cAAQ,OAAO;AAAA,IACjB;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,MAAc;AACrC,SAAO,KACJ,QAAQ,wBAAwB,EAAE,EAClC,QAAQ,aAAa,EAAE,EACvB,QAAQ,uFAAuF,EAAE;AACtG;;;ACjGA,eAAsB,iBAAiB,KAAe,KAAU,QAAgC;AAE9F,SAAO,IAAI,aAAa,EACrB,GAAG,SAAS,IAAI,aAAa,QAAQ,GAAG,CAAC,EACzC,GAAG,QAAQ,IAAI,aAAa,QAAQ,GAAG,CAAC,EACxC,GAAG,QAAQ,IAAI,aAAa,MAAM,CAAC,EACnC,GAAG,QAAQ,IAAI,aAAa,MAAM,CAAC,EACnC,UAAU,GAAG;AAClB;;;ACVA,SAAS,gBAAAC,qBAAoB;AAI7B,eAAsB,yBAAyB,KAAe,KAAU,QAAgC;AAEtG,SAAO,IAAIC,cAAa,EACrB,GAAG,SAAS,IAAI,aAAa,QAAQ,GAAG,CAAQ,EAChD,GAAG,QAAQ,IAAI,aAAa,QAAQ,GAAG,CAAQ,EAC/C,GAAG,QAAQ,IAAI,aAAa,MAAM,CAAQ,EAC1C,GAAG,QAAQ,IAAI,aAAa,MAAM,CAAQ,EAC1C,UAAU,GAAG;AAClB;;;ACbA,eAAsB,cAAc,KAAU,UAAkB;AAC9D,QAAM,WAAW,MAAM,MAAM,QAAQ;AACrC,QAAM,OAAO,MAAM,SAAS,YAAY;AACxC,QAAM,MAAM,IAAI,SAAS,MAAM,QAAQ;AAEvC,SAAO;AACT;;;ACNA,eAAsB,kBAAkB,KAAU;AAChD,QAAM,WAAW,MAAM,MAAM,IAAI,SAAS,CAAC;AAC3C,QAAM,OAAO,MAAM,SAAS,YAAY;AACxC,QAAM,MAAM,IAAI,SAAS,MAAM,QAAQ;AAEvC,SAAO;AACT;;;ACLA,eAAsB,UAAU,KAAU,SAAkB;AAE1D,QAAM,WAAW,MAAM,MAAM,IAAI,SAAS,GAAG;AAAA,IAC3C,MAAM,IAAI,SAAS,WAAW,2BAA2B,IAAI,OAAO,QAAQ;AAAA,IAC5E,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,cACE;AAAA,IACJ;AAAA,IACA,QAAQ;AAAA,EACV,CAAC;AACD,QAAM,MAAM,IAAI,SAAS,SAAS,MAAkB,QAAQ;AAE5D,MAAI,QAAQ,IAAI,+BAA+B,GAAG;AAElD,SAAO;AACT;;;ACfA,eAAsB,YAAY,KAAUC,aAAoC;AAC9E,QAAM,EAAE,OAAO,IAAIA;AACnB,QAAM,WAAW,MAAM,MAAM,IAAI,SAAS,CAAC;AAC3C,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAM,YAAY,IAAI;AAAA,IACpBA,YAAW,eAAe,GAAGA,YAAW,YAAY,iBAAiB;AAAA,IACrE;AAAA,EACF;AACA,QAAM,MAAM,IAAI,SAAS,KAAK,QAAQ,WAAW,MAAM,EAAE,QAAQ,cAAc,MAAM,GAAG,QAAQ;AAEhG,MAAI,QAAQ,IAAI,gBAAgB,0BAA0B;AAE1D,SAAO;AACT;;;ACfA,eAAsB,SAAS,KAAU;AACvC,QAAM,WAAW,MAAM,MAAM,IAAI,SAAS,CAAC;AAC3C,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAM,MAAM,IAAI,SAAS,MAAM,QAAQ;AAEvC,MAAI,QAAQ,IAAI,gBAAgB,0BAA0B;AAE1D,SAAO;AACT;;;ACRA,IAAM,cAAc;AAAA,EAClB,+BAA+B;AAAA,EAC/B,gCAAgC;AAAA,EAChC,gCAAgC;AAClC;AAEO,SAAS,cAAc,SAAkB;AAC9C,MACE,QAAQ,QAAQ,IAAI,QAAQ,MAAM,QAClC,QAAQ,QAAQ,IAAI,+BAA+B,MAAM,QACzD,QAAQ,QAAQ,IAAI,gCAAgC,MAAM,MAC1D;AAEA,WAAO,IAAI,SAAS,MAAM;AAAA,MACxB,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAGA,SAAO,IAAI,SAAS,MAAM;AAAA,IACxB,SAAS;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;;;ACtBO,SAAS,cAAc,SAAkBC,aAAoC;AAClF,QAAM,EAAE,QAAQ,MAAM,IAAIA;AAC1B,MAAI,UAAU;AAEd,QAAM,QAAQ,CAAC,SAAS;AACtB,eAAW,qBAAqB,MAAM,IAAI,IAAI;AAAA,EAChD,CAAC;AACD,aAAW;AAEX,QAAM,WAAW,IAAI,SAAS,OAAO;AAErC,WAAS,QAAQ,IAAI,gBAAgB,iBAAiB;AAEtD,SAAO;AACT;;;ACdO,IAAI,aAAqC,CAAC;AAE1C,SAAS,uBAAuB,gBAAoC;AACzE,eAAa;AAAA,IACX,GAAG;AAAA,IACH,OAAO,CAAC;AAAA,IACR,OAAO,CAAC;AAAA,IACR,YAAY,CAAC;AAAA,EACf;AAEA,aAAW,eAAe,WAAW,gBAAgB,CAAC;AAEtD,aAAW,MAAM;AAAA,IACf,MAAM,WAAW,KAAK;AAAA,IACtB,MAAM,WAAW,KAAK,QAAQ;AAAA,EAChC;AAEA,MAAI,WAAW,IAAI,MAAM,QAAQ;AAC/B,eAAW,WAAW,WAAW,IAAI,IAAI,IAAI,WAAW,IAAI;AAAA,EAC9D;AAGA,SAAO,KAAK,WAAW,UAAU,EAAE,QAAQ,CAAC,SAAS;AACnD,UAAM,SAAS,WAAW,WAAW,IAAI;AAEzC,eAAW,MAAM,KAAK,IAAI;AAC1B,eAAW,MAAM,KAAK,MAAM;AAC5B,eAAW,WAAW,MAAM,IAAI;AAAA,EAClC,CAAC;AACH;;;ACvBA,eAAsB,aACpB,SACA,OAEI,EAAE,YAAY,KAAK,GACvB;AACA,QAAM,EAAE,WAAW,IAAI;AAEvB,MAAI,CAAC,YAAY;AACf,UAAM,IAAI,MAAM,6EAA6E;AAAA,EAC/F;AAEA,QAAM,EAAE,QAAQ,YAAY,SAAS,IAAI;AAEzC,MAAI,QAAQ,WAAW,WAAW;AAChC,WAAO,cAAc,OAAO;AAAA,EAC9B;AAEA,QAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,QAAM,YAAY,IAAI,SAAS,MAAM,GAAG,EAAE,CAAC;AAE3C,MAAI,IAAI,aAAa,QAAQ;AAC3B,QAAI,WAAW,WAAW,eAAe,GAAG,WAAW,YAAY,iBAAiB;AAGpF,QAAI,IAAI,aAAa,eAAe;AAClC,aAAO,IAAI,SAAS,oBAAoB,MAAM,cAAc;AAAA,IAC9D;AAEA,QAAI,IAAI,aAAa,gBAAgB;AACnC,aAAO,cAAc,SAAS,UAAU;AAAA,IAC1C;AAEA,QAAI,IAAI,SAAS,WAAW,MAAM,KAAK,IAAI,SAAS,SAAS,IAAI,GAAG;AAClE,aAAO,YAAY,KAAK,UAAU;AAAA,IACpC;AAEA,QAAI,IAAI,SAAS,WAAW,MAAM,GAAG;AACnC,aAAO,UAAU,KAAK,OAAO;AAAA,IAC/B;AAEA,QAAI,IAAI,SAAS,SAAS,KAAK,GAAG;AAChC,aAAO,SAAS,GAAG;AAAA,IACrB;AAEA,QAAI,IAAI,SAAS,SAAS,aAAa,KAAK,UAAU;AACpD,aAAO,cAAc,KAAK,QAAQ;AAAA,IACpC;AAEA,QACE,IAAI,SAAS,WAAW,UAAU,KAClC,IAAI,SAAS,WAAW,QAAQ,KAChC,IAAI,SAAS,WAAW,YAAY,KACpC,IAAI,SAAS,MAAM,kBAAkB,GACrC;AACA,aAAO,kBAAkB,GAAG;AAAA,IAC9B;AAGA,YAAQ,IAAI,gBAAgB,IAAI,QAAQ;AAExC,UAAM,OAAO,IAAI,SAAS,MAAM,GAAG,EAAE,IAAI;AACzC,UAAM,WAAW,IAAI,SAAS,MAAM,GAAG;AACvC,UAAM,OAAO,WAAW,IAAI;AAE5B,QAAI,MAAM;AACR,cAAQ,IAAI,eAAe,IAAI,eAAe,MAAM,IAAI,IAAI,EAAE;AAE9D,aAAO,SAAS,SAAS,WAAW,MAAM,IAAI,IAAI,IAAI,GAAG;AAAA,IAC3D,WAAW,YAAY,aAAa,QAAQ,SAAS,WAAW,IAAI;AAClE,cAAQ,IAAI,eAAe,IAAI,eAAe,MAAM,IAAI,QAAQ,EAAE;AAElE,aAAO,SAAS,SAAS,WAAW,MAAM,IAAI,QAAQ,IAAI,GAAG;AAAA,IAC/D,WAAW,QAAQ,KAAK,WAAW,IAAI;AACrC,UAAI,WAAW,KAAK,MAAM,QAAQ;AAChC,eAAO,SAAS,SAAS,WAAW,MAAM,IAAI,WAAW,IAAI,IAAI,IAAI,GAAG;AAAA,MAC1E,OAAO;AACL,gBAAQ,MAAM,2BAA2B,IAAI,QAAQ;AAErD,eAAO,IAAI,SAAS,mCAAmC,EAAE,QAAQ,IAAI,CAAC;AAAA,MACxE;AAAA,IACF;AAAA,EACF,WAAW,aAAa,WAAW,YAAY;AAC7C,UAAM,MAAM,WAAW,WAAW,SAAS;AAE3C,QAAI,KAAK;AAGP,aAAO,SAAS,SAAS,IAAI,UAAU,GAAG;AAAA,IAC5C;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,MAAM,IAAI,SAAS,GAAG;AAAA,IAC3C,MAAM,QAAQ;AAAA,IACd,SAAS,QAAQ;AAAA,IACjB,QAAQ,QAAQ;AAAA,EAClB,CAAC;AACD,QAAM,MAAM,IAAI,SAAS,SAAS,MAAkB,QAAQ;AAE5D,MAAI,QAAQ,OAAO,yBAAyB;AAC5C,MAAI,QAAQ,OAAO,2BAA2B;AAE9C,SAAO,aAAa,iBAAiB,KAAK,KAAK,UAAU,IAAI,yBAAyB,KAAK,KAAK,UAAU;AAC5G;","names":["siteConfig","siteConfig","siteConfig","HTMLRewriter","HTMLRewriter","siteConfig","siteConfig"]}
{
"name": "notehost",
"version": "1.0.32",
"version": "1.0.33",
"description": "NoteHost is a free and powerful Notion hosting service.",

@@ -28,2 +28,10 @@ "repository": "https://github.com/velsa/notehost",

},
"scripts": {
"prebuild": "./build-body-js-string.sh",
"dev:cli": "npx tsx --inspect src/cli/index.ts init test.com",
"build": "npm run prebuild && tsup src/index.ts --format cjs,esm --dts-resolve --clean --sourcemap --out-dir dist && npm run build:cli",
"build:cli": "tsup src/cli/index.ts --format esm --clean --out-dir dist/cli",
"release": "npm run build && changeset publish",
"lint": "echo Fix lint!"
},
"dependencies": {

@@ -51,11 +59,3 @@ "@inquirer/prompts": "^3.3.2",

"wrangler": "^3.0.0"
},
"scripts": {
"prebuild": "./build-body-js-string.sh",
"dev:cli": "npx tsx --inspect src/cli/index.ts init test.com",
"build": "npm run prebuild && tsup src/index.ts --format cjs,esm --dts-resolve --clean --sourcemap --out-dir dist && npm run build:cli",
"build:cli": "tsup src/cli/index.ts --format esm --clean --out-dir dist/cli",
"release": "npm run build && changeset publish",
"lint": "echo Fix lint!"
}
}
}

@@ -0,1 +1,2 @@

/* eslint-disable @typescript-eslint/no-explicit-any */
import { HTMLRewriter } from 'htmlrewriter'

@@ -2,0 +3,0 @@ import { NoteHostSiteConfigFull } from '.'

@@ -68,10 +68,17 @@ /* eslint-disable no-undef */

// Handle slugs, from site-config and from KV
const slugHash = url.pathname.split('/').pop().split('-').pop()
const page = slugToPage[slugHash]
console.log('url.pathname', url.pathname)
const slug = url.pathname.split('/').pop()
const slugHash = url.pathname.slice(-32)
const page = slugToPage[slug]
if (page) {
// console.log(`Redirecting ${slug} to https://${domain}/${page}`);
console.log(`Redirecting ${slug} to https://${domain}/${page}`)
return Response.redirect(`https://${domain}/${page}`, 301)
} else if (slugHash.length !== 32 && !slugHash.match(/^[0-9a-f]+$/i)) {
} else if (slugHash && slugHash !== slug && slugHash.length === 32) {
console.log(`Redirecting ${slug} to https://${domain}/${slugHash}`)
return Response.redirect(`https://${domain}/${slugHash}`, 301)
} else if (slug && slug.length !== 32) {
if (siteConfig.fof?.page?.length) {

@@ -78,0 +85,0 @@ return Response.redirect(`https://${domain}/${siteConfig.fof.page}`, 301)

@@ -108,4 +108,5 @@ export const BODY_JS_STRING = `

// console.log('redirected', getSlug())
updateSlug()
redirected = true
updateSlug()
addDarkModeButton(nav ? 'web' : 'mobile')

@@ -138,4 +139,12 @@

const { replaceState } = window.history
const { replaceState, back, forward } = window.history
window.history.back = function () {
back.apply(window.history, arguments)
}
window.history.forward = function () {
forward.apply(window.history, arguments)
}
window.history.replaceState = function () {

@@ -146,8 +155,11 @@ if (arguments[1] === 'bypass') {

// console.log('replaceState arguments:', arguments)
// console.log('replaceState state:', state)
const slug = getSlug()
const isKnownSlug = slugs.includes(slug)
if (isKnownSlug && location.pathname !== ['/', slug].join('')) {
console.log('replaceState:', { slug, isKnownSlug, arguments })
// console.log('replaceState arguments:', arguments)
// console.log('replaceState state:', state)
if (arguments[2] === '/login') {
const page = SLUG_TO_PAGE[slug]

@@ -159,3 +171,11 @@

arguments[2] = ['/', page].join('')
replaceState.apply(window.history, arguments)
window.location.reload()
return
}
} else {
if (isKnownSlug && arguments[2] !== ['/', slug].join('')) {
return
}
}

@@ -162,0 +182,0 @@

@@ -107,4 +107,5 @@ /* eslint-disable no-unused-vars */

// console.log('redirected', getSlug())
updateSlug()
redirected = true
updateSlug()
addDarkModeButton(nav ? 'web' : 'mobile')

@@ -137,4 +138,12 @@

const { replaceState } = window.history
const { replaceState, back, forward } = window.history
window.history.back = function () {
back.apply(window.history, arguments)
}
window.history.forward = function () {
forward.apply(window.history, arguments)
}
window.history.replaceState = function () {

@@ -145,8 +154,11 @@ if (arguments[1] === 'bypass') {

// console.log('replaceState arguments:', arguments)
// console.log('replaceState state:', state)
const slug = getSlug()
const isKnownSlug = slugs.includes(slug)
if (isKnownSlug && location.pathname !== ['/', slug].join('')) {
console.log('replaceState:', { slug, isKnownSlug, arguments })
// console.log('replaceState arguments:', arguments)
// console.log('replaceState state:', state)
if (arguments[2] === '/login') {
const page = SLUG_TO_PAGE[slug]

@@ -158,3 +170,11 @@

arguments[2] = ['/', page].join('')
replaceState.apply(window.history, arguments)
window.location.reload()
return
}
} else {
if (isKnownSlug && arguments[2] !== ['/', slug].join('')) {
return
}
}

@@ -161,0 +181,0 @@