@open-condo/miniapp-utils
Version:
A set of helper functions / components / hooks used to build new condo apps fast
1 lines • 49 kB
Source Map (JSON)
{"version":3,"sources":["../../../src/helpers/messaging/provider.tsx","../../../src/helpers/messaging/controller.ts","../../../src/helpers/messaging/errors.ts","../../../src/helpers/messaging/events/bridge.ts","../../../src/helpers/ip/utils.ts","../../../src/helpers/urls.ts","../../../src/helpers/uuid.ts","../../../src/helpers/messaging/utils.ts"],"sourcesContent":["import React, { createContext, useState, useEffect, useContext, useMemo } from 'react'\n\nimport { PostMessageController } from './controller'\n\nimport type { RegisterBridgeEventsOptions } from './events/bridge'\nimport type { ControllerState } from './types'\n\n// NOTE: Magic hook to make framework-agnostic controller reactive and observable\nfunction useControllerState (controller: PostMessageController): ControllerState {\n const [controllerState, setControllerState] = useState(controller.state)\n\n useEffect(() => {\n const handleBridgeReadyChange = (event: CustomEvent) => {\n setControllerState(event.detail)\n }\n\n controller.addEventListener('statechange', handleBridgeReadyChange as EventListener)\n return () => {\n controller.removeEventListener('statechange', handleBridgeReadyChange as EventListener)\n }\n }, [controller])\n\n return controllerState\n}\n\ntype PostMessageContextType = Pick<PostMessageController,\n'addFrame' |\n'removeFrame' |\n'addHandler' |\n'addMiddleware' |\n'removeMiddleware'\n> & ControllerState\n\nconst PostMessageContext = createContext<PostMessageContextType>({\n addFrame: () => '',\n removeFrame: () => {},\n addHandler: () => {},\n addMiddleware: () => '',\n removeMiddleware: () => {},\n isBridgeReady: false,\n})\n\ntype PostMessageProviderProps = Partial<Omit<RegisterBridgeEventsOptions, 'addHandler'>>\n\nexport const PostMessageProvider: React.FC<React.PropsWithChildren<PostMessageProviderProps>> = ({ children, router, notificationsApi, modalsApi }) => {\n const [controller] = useState(() => new PostMessageController())\n const controllerState = useControllerState(controller)\n\n useEffect( () => {\n controller.registerBridgeEvents({ router, notificationsApi, modalsApi })\n }, [controller, modalsApi, notificationsApi, router])\n\n useEffect(() => {\n window.addEventListener('message', controller.eventListener)\n return () => {\n window.removeEventListener('message', controller.eventListener)\n }\n }, [controller.eventListener])\n\n useEffect(() => {\n window?.navigator?.serviceWorker?.addEventListener('message', controller.eventListener)\n return () => {\n window?.navigator?.serviceWorker?.removeEventListener('message', controller.eventListener)\n }\n }, [controller.eventListener])\n\n const contextValue: PostMessageContextType = useMemo(() => ({\n ...controllerState,\n addFrame: controller.addFrame,\n removeFrame: controller.removeFrame,\n addHandler: controller.addHandler,\n addMiddleware: controller.addMiddleware,\n removeMiddleware: controller.removeMiddleware,\n }), [controller, controllerState])\n\n return (\n <PostMessageContext.Provider value={contextValue}>\n {children}\n </PostMessageContext.Provider>\n )\n}\n\nexport function usePostMessageContext (): PostMessageContextType {\n return useContext(PostMessageContext)\n}","import { z } from 'zod'\n\nimport { getClientErrorMessage } from './errors'\nimport { registerBridgeEvents } from './events/bridge'\nimport { sortedMiddlewares, isServiceWorker, sendResponseMessage } from './utils'\n\nimport { generateUUIDv4 } from '../uuid'\n\nimport type { RegisterBridgeEventsOptions } from './events/bridge'\nimport type {\n ControllerState,\n DataStorage,\n EventName,\n EventParams,\n EventType,\n FrameId,\n RegisteredFrame,\n SourceMetadata,\n MessageSource,\n FrameType,\n Handler,\n HandlerMethods,\n HandlerResult,\n HandlerScope,\n Middleware,\n MiddlewareFn,\n MiddlewareNextFn,\n MiddlewareId,\n ParamsValidator,\n RegisteredMiddleware,\n} from './types'\n\n// NOTE: taken from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string\nconst SEMVER_REGEXP = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$/\n\n\nconst MESSAGE_SCHEMA = z.object({\n handler: z.string(),\n params: z.record(z.string(), z.unknown()).and(z.object({\n requestId: z.union([z.string(), z.number()]).optional(),\n })),\n type: z.string(),\n version: z.string().regex(SEMVER_REGEXP),\n}).strict()\n\nexport class PostMessageController extends EventTarget {\n #registeredFrames: Record<FrameId, RegisteredFrame> = {}\n #registeredHandlers: Record<HandlerScope, Record<EventType, Record<EventName, HandlerMethods<EventParams, HandlerResult>>>> = {}\n #registeredMiddlewares: Record<HandlerScope, Array<RegisteredMiddleware<EventParams, HandlerResult>>> = {}\n #middlewaresIdsMap: Record<MiddlewareId, HandlerScope> = {}\n #storage: DataStorage = {}\n state: ControllerState = { isBridgeReady: false }\n\n constructor () {\n super()\n this.addFrame = this.addFrame.bind(this)\n this.removeFrame = this.removeFrame.bind(this)\n this.addHandler = this.addHandler.bind(this)\n this.eventListener = this.eventListener.bind(this)\n this.registerBridgeEvents = this.registerBridgeEvents.bind(this)\n this.addMiddleware = this.addMiddleware.bind(this)\n this.removeMiddleware = this.removeMiddleware.bind(this)\n }\n\n // ---- PRIVATE UTILITIES METHODS ----\n\n private updateState (state: Partial<ControllerState>) {\n this.state = { ...this.state, ...state }\n this.dispatchEvent(new CustomEvent('statechange', { detail: this.state }))\n }\n\n private getWrappedHandler (eventType: EventType, eventName: EventName, scope: HandlerScope, handler: Handler<EventParams, HandlerResult>): Handler<EventParams, HandlerResult> {\n const globalMiddlewares = (this.#registeredMiddlewares['*'] ?? [])\n .filter(mw =>\n (!mw.eventType || mw.eventType === eventType) &&\n (!mw.eventName || mw.eventName === eventName) &&\n (mw.scope === '*')\n )\n const scopedMiddlewares = (this.#registeredMiddlewares[scope] ?? [])\n .filter(mw =>\n (!mw.eventType || mw.eventType === eventType) &&\n (!mw.eventName || mw.eventName === eventName) &&\n (mw.scope === scope)\n )\n\n // NOTE: sort middlewares by execution order\n const middlewares = sortedMiddlewares([...globalMiddlewares, ...scopedMiddlewares])\n\n return middlewares.reduceRight<Handler<EventParams, HandlerResult>>(\n (nextHandler, mw) => {\n return async (args) => {\n const nextMiddlewareFn: MiddlewareNextFn<EventParams, HandlerResult> = (nextArgs) => {\n return nextHandler({\n ...args,\n params: nextArgs?.params ?? args.params,\n })\n }\n\n return mw.fn({\n ...args,\n next: nextMiddlewareFn,\n })\n }\n },\n handler\n )\n }\n\n private getMessageSource (source: Window | ServiceWorker): MessageSource | null {\n if (isServiceWorker(source)) {\n if (source !== navigator.serviceWorker.controller) return null\n return {\n ref: source,\n id: 'worker',\n type: 'worker',\n }\n }\n if (source === window) {\n return {\n ref: source,\n id: 'parent',\n type: 'window',\n }\n }\n\n const registeredFrame = Object.entries(this.#registeredFrames)\n .find(([, frame]) => frame.ref.contentWindow === source)\n\n if (!registeredFrame) return null\n\n return {\n ref: registeredFrame[1].ref,\n id: registeredFrame[0],\n type: 'frame',\n metadata: registeredFrame[1].metadata,\n }\n }\n\n // ---- SOURCE REGISTRATION METHODS ----\n\n addFrame (frame: FrameType, metadata?: SourceMetadata): FrameId {\n const registeredFrame = Object.entries(this.#registeredFrames)\n .find(([, existingFrame]) => existingFrame.ref === frame)\n if (registeredFrame) {\n this.#registeredFrames[registeredFrame[0]].metadata = metadata\n return registeredFrame[0]\n }\n\n const frameId = generateUUIDv4()\n this.#registeredFrames[frameId] = { ref: frame, metadata }\n return frameId\n }\n\n removeFrame (frameId: FrameId) {\n (this.#registeredMiddlewares[frameId] ?? []).forEach(mw => {\n delete this.#middlewaresIdsMap[mw.id]\n })\n delete this.#registeredFrames[frameId]\n delete this.#registeredHandlers[frameId]\n delete this.#registeredMiddlewares[frameId]\n }\n\n // ---- HANDLER REGISTRATION METHODS ----\n\n addHandler<Params extends EventParams, Result extends HandlerResult>(\n eventType: EventType,\n eventName: EventName,\n handlerScope: HandlerScope,\n validator: ParamsValidator<Params>,\n handler: Handler<Params, Result>\n ) {\n if (!this.#registeredHandlers[handlerScope]) {\n this.#registeredHandlers[handlerScope] = {}\n }\n const scopedHandlers = this.#registeredHandlers[handlerScope]\n if (!scopedHandlers[eventType]) {\n scopedHandlers[eventType] = {}\n }\n const eventHandlers = scopedHandlers[eventType]\n eventHandlers[eventName] = { validator, handler } as HandlerMethods<EventParams, HandlerResult>\n }\n\n addMiddleware<Params extends EventParams, Result extends HandlerResult>(mw: Middleware<Params, Result>): MiddlewareId {\n const { scope } = mw\n if (!this.#registeredMiddlewares[scope]) {\n this.#registeredMiddlewares[scope] = []\n }\n const id = generateUUIDv4()\n this.#registeredMiddlewares[scope].push({\n ...mw,\n fn: mw.fn as MiddlewareFn<EventParams, HandlerResult>,\n id,\n })\n this.#middlewaresIdsMap[id] = scope\n\n return id\n }\n\n removeMiddleware (id: MiddlewareId): void {\n const scope = this.#middlewaresIdsMap[id]\n if (scope && this.#registeredMiddlewares[scope]) {\n this.#registeredMiddlewares[scope] = this.#registeredMiddlewares[scope].filter(mw => mw.id !== id)\n }\n delete this.#middlewaresIdsMap[id]\n }\n\n // ---- EVENT LISTENERS ----\n\n async eventListener (event: MessageEvent) {\n if (typeof window === 'undefined') return\n if (!event.isTrusted || !event.source || (!('self' in event.source) && !isServiceWorker(event.source))) return\n\n const { success: isValidMessage, data: message } = MESSAGE_SCHEMA.safeParse(event.data)\n if (!isValidMessage) return\n\n const { handler: eventName, params: { requestId, ...handlerParams }, type: eventType } = message\n\n const messageSource = this.getMessageSource(event.source)\n\n if (!messageSource) {\n return sendResponseMessage({\n data: getClientErrorMessage('ACCESS_DENIED', 0, 'Message was received from unregistered origin / iframe', requestId, eventName),\n target: event.source,\n origin: event.origin,\n })\n }\n\n const handlerMethods = (\n this.#registeredHandlers[messageSource.id]?.[eventType]?.[eventName]\n ?? this.#registeredHandlers['*']?.[eventType]?.[eventName]\n ?? {}\n )\n\n const { handler, validator } = handlerMethods\n if (!handler || !validator) {\n return sendResponseMessage({\n data: getClientErrorMessage('UNKNOWN_METHOD', 2, 'Unknown method was provided. Make sure your runtime environment supports it.', requestId),\n origin: event.origin,\n target: event.source,\n })\n }\n\n const validationResult = validator(handlerParams)\n if (!validationResult.success) {\n return sendResponseMessage({\n data: getClientErrorMessage('INVALID_PARAMETERS', 3, validationResult.error, requestId, eventName),\n origin: event.origin,\n target: event.source,\n })\n }\n\n const validatedParams = validationResult.data\n this.#storage[eventType] ??= new Map()\n const eventsStorage = this.#storage[eventType]\n const wrappedHandler = this.getWrappedHandler(eventType, eventName, messageSource.id, handler)\n\n try {\n const result = await wrappedHandler({\n eventType,\n eventName,\n params: validatedParams,\n storage: { events: eventsStorage },\n source: messageSource,\n })\n\n return sendResponseMessage({\n data: {\n type: `${eventName}Result`,\n data: {\n ...result,\n requestId,\n },\n },\n target: event.source,\n origin: event.origin,\n })\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err)\n\n return sendResponseMessage({\n data: getClientErrorMessage('HANDLER_ERROR', 4, errorMessage, requestId, eventName),\n target: event.source,\n origin: event.origin,\n })\n }\n }\n\n // ---- COMMON HANDLERS METHODS ----\n\n registerBridgeEvents (options: Omit<RegisterBridgeEventsOptions, 'addHandler'>) {\n registerBridgeEvents({\n ...options,\n addHandler: this.addHandler,\n })\n this.updateState({ isBridgeReady: true })\n }\n}","import type { ErrorReason, ErrorCode } from '@open-condo/bridge'\n\nexport function getClientErrorMessage<Reason extends ErrorReason> (\n reason: Reason,\n code: ErrorCode<Reason>,\n message: string,\n requestId?: string | number,\n eventName?: string\n) {\n return {\n type: eventName ? `${eventName}Error` : 'CondoWebAppCommonError',\n data: {\n errorType: 'client',\n errorCode: code,\n errorReason: reason,\n errorMessage: message,\n ...(typeof requestId !== 'undefined' ? { requestId } : null),\n },\n }\n}","import { z } from 'zod'\n\nimport type {\n GetFragmentData,\n GetFragmentParams,\n RedirectData,\n RedirectParams,\n RequestAuthData,\n RequestAuthParams,\n ResizeWindowData,\n ResizeWindowParams,\n ShowModalWindowData,\n ShowModalWindowParams,\n ShowNotificationData,\n ShowNotificationParams,\n UpdateModalWindowData,\n UpdateModalWindowParams,\n CloseModalWindowData,\n CloseModalWindowParams,\n CondoBridgeResultResponseEvent,\n} from '@open-condo/bridge'\n\n\nimport { isSafeUrl } from '../../urls'\nimport { generateUUIDv4 } from '../../uuid'\nimport { zodSchemaToValidator, sendResponseMessage } from '../utils'\n\nimport type { SourceMetadata } from '../types'\nimport type { AddHandlerType } from '../types'\n\ntype SimpleRouter = {\n push(url: string): unknown\n}\n\nexport type NotificationsApi = (params: ShowNotificationParams) => void\n\ntype ExtraShowModalParams = {\n onCancel?: () => void\n metadata?: SourceMetadata\n}\nexport type ModalsApi = (params: ShowModalWindowParams & ExtraShowModalParams) => {\n update(params: UpdateModalWindowParams['data']): void\n destroy(): void\n}\n\nexport type RegisterBridgeEventsOptions = {\n addHandler: AddHandlerType\n router?: SimpleRouter\n notificationsApi?: NotificationsApi\n modalsApi?: ModalsApi\n}\n\nexport function registerBridgeEvents ({\n addHandler,\n router,\n notificationsApi,\n modalsApi,\n}: RegisterBridgeEventsOptions) {\n addHandler<ResizeWindowParams, ResizeWindowData>('condo-bridge', 'CondoWebAppResizeWindow', '*', zodSchemaToValidator(z.strictObject({\n height: z.number(),\n })), ({ params, source }) => {\n if (source.type !== 'frame') {\n throw new Error('Forbidden source type. Resize window is only available for registered iframes')\n }\n\n source.ref.height = `${params.height}px`\n\n return { height: params.height }\n })\n addHandler<GetFragmentParams, GetFragmentData>('condo-bridge', 'CondoWebAppGetFragment', '*', zodSchemaToValidator(z.strictObject({})), () => {\n const hash = window.location.hash\n const rawFragment = hash.startsWith('#') ? hash.substring(1) : hash\n const fragment = decodeURIComponent(rawFragment)\n\n return { fragment }\n })\n\n addHandler<RedirectParams, RedirectData>('condo-bridge', 'CondoWebAppRedirect', '*', zodSchemaToValidator(z.strictObject({\n url: z.url(),\n target: z.union([z.literal('_blank'), z.literal('_self')]),\n })), async ({\n params: { url, target },\n }) => {\n if (!isSafeUrl(url)) {\n throw new Error('Forbidden url. Your url is probably injected')\n }\n\n if (target === '_blank') {\n window.open(url, target)\n } else {\n const urlOrigin = (new URL(url)).origin\n if (window.origin !== urlOrigin) {\n throw new Error('The redirect url must have the same origin as parent window, if target is not _blank')\n }\n if (router) {\n router.push(url)\n } else {\n window.open(url, target)\n }\n }\n\n return { success: true }\n })\n\n addHandler<RequestAuthParams, RequestAuthData>('condo-bridge', 'CondoWebAppRequestAuth', '*', zodSchemaToValidator(z.strictObject({\n url: z.url(),\n })), async ({\n params: { url },\n }) => {\n if (!isSafeUrl(url)) {\n throw new Error('Forbidden url. Your url is probably injected')\n }\n\n const response = await fetch(url, { credentials: 'include' })\n const body = await response.text()\n\n return { response: { status: response.status, body, url: response.url } }\n })\n\n if (notificationsApi) {\n addHandler<ShowNotificationParams, ShowNotificationData>('condo-bridge', 'CondoWebAppShowNotification', '*', zodSchemaToValidator(z.strictObject({\n message: z.string(),\n description: z.string().optional(),\n type: z.enum(['success', 'error', 'warning', 'info']),\n })), ({ params }) => {\n notificationsApi(params)\n return { success: true }\n })\n }\n\n if (modalsApi) {\n addHandler<ShowModalWindowParams, ShowModalWindowData>('condo-bridge', 'CondoWebAppShowModalWindow', '*', zodSchemaToValidator(z.strictObject({\n title: z.string(),\n url: z.url(),\n size: z.enum(['big', 'small']).optional(),\n initialHeight: z.number().optional(),\n })), ({\n source,\n params,\n storage,\n }) => {\n if (source.type === 'worker') {\n throw new Error('Forbidden source type. Modals cannot be opened from service workers')\n }\n\n const modalId = generateUUIDv4()\n if (!isSafeUrl(params.url)) {\n throw new Error('Forbidden url. Your url is probably injected')\n }\n const originalSrc = new URL(params.url)\n originalSrc.searchParams.set('modalId', modalId)\n\n const sourceOrigin = new URL(source.type === 'frame' ? source.ref.src : window.location.href).origin\n const sourceTarget = source.type === 'frame' ? source.ref.contentWindow : source.ref\n\n if (sourceOrigin && originalSrc.origin !== sourceOrigin) {\n throw new Error('Forbidden url. Url must have same origin as sender')\n }\n\n const closeEventData: CondoBridgeResultResponseEvent<'CondoWebAppCloseModalWindow'> = {\n type: 'CondoWebAppCloseModalWindowResult',\n data: {\n success: true,\n modalId,\n },\n }\n\n const onCancel = () => {\n storage.events.delete(`modals:${modalId}`)\n if (sourceTarget) {\n sendResponseMessage({\n data: closeEventData,\n target: sourceTarget,\n origin: sourceOrigin,\n })\n }\n }\n\n storage.events.set(`modals:${modalId}`, modalsApi({\n ...params,\n url: originalSrc.toString(),\n onCancel,\n metadata: source.type === 'frame' ? source.metadata : undefined,\n }))\n\n return { modalId }\n })\n\n addHandler<UpdateModalWindowParams, UpdateModalWindowData>('condo-bridge', 'CondoWebAppUpdateModalWindow', '*', zodSchemaToValidator(z.strictObject({\n modalId: z.string(),\n data: z.strictObject({\n title: z.string().optional(),\n size: z.enum(['big', 'small']).optional(),\n }),\n })), ({ params, storage }) => {\n const modalActions = storage.events.get(`modals:${params.modalId}`) as ReturnType<ModalsApi>\n if (!modalActions) {\n return { updated: false }\n }\n\n modalActions.update(params.data)\n\n return { updated: true }\n })\n\n // NOTE: make sure to keep * scope, so parent window can close modals too\n addHandler<CloseModalWindowParams, CloseModalWindowData>('condo-bridge', 'CondoWebAppCloseModalWindow', '*', zodSchemaToValidator(z.strictObject({\n modalId: z.string(),\n })), ({ params, storage }) => {\n const modalActions = storage.events.get(`modals:${params.modalId}`) as ReturnType<ModalsApi>\n if (!modalActions) {\n return { modalId: params.modalId, success: false }\n }\n\n modalActions.destroy()\n storage.events.delete(`modals:${params.modalId}`)\n\n return { modalId: params.modalId, success: true }\n })\n }\n}","// RegExp for testing if a string represents an IPv4 address\nconst v4Seg = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'\nconst v4Str = `(${v4Seg}[.]){3}${v4Seg}`\nconst IPv4Reg = new RegExp(`^${v4Str}$`)\n\n// RegExp for testing if a string represents an IPv6 address\nconst v6Seg = '(?:[0-9a-fA-F]{1,4})'\nconst IPv6Reg = new RegExp(\n '^(' +\n `(?:${v6Seg}:){7}(?:${v6Seg}|:)|` +\n `(?:${v6Seg}:){6}(?:${v4Str}|:${v6Seg}|:)|` +\n `(?:${v6Seg}:){5}(?::${v4Str}|(:${v6Seg}){1,2}|:)|` +\n `(?:${v6Seg}:){4}(?:(:${v6Seg}){0,1}:${v4Str}|(:${v6Seg}){1,3}|:)|` +\n `(?:${v6Seg}:){3}(?:(:${v6Seg}){0,2}:${v4Str}|(:${v6Seg}){1,4}|:)|` +\n `(?:${v6Seg}:){2}(?:(:${v6Seg}){0,3}:${v4Str}|(:${v6Seg}){1,5}|:)|` +\n `(?:${v6Seg}:){1}(?:(:${v6Seg}){0,4}:${v4Str}|(:${v6Seg}){1,6}|:)|` +\n `(?::((?::${v6Seg}){0,5}:${v4Str}|(?::${v6Seg}){1,7}|:))` +\n ')(%[0-9a-zA-Z]{1,})?$'\n)\n\n/**\n * Returns true if the string represents an IPv4 address. Matches Node.js net.isIPv4\n * functionality.\n */\nexport function isIPv4 (s: string) {\n return IPv4Reg.test(s)\n}\n\n/**\n * Returns true if the string represents an IPv6 address. Matches Node.js net.isIPv6\n * functionality.\n */\nexport function isIPv6 (s: string) {\n return IPv6Reg.test(s)\n}\n\nexport function isIP (s: string) {\n if (isIPv4(s)) return 4\n if (isIPv6(s)) return 6\n return 0\n}\n","const REGEXP_ESCAPE_CHARS = /[\\\\^$.*+?()[\\]{}|]/g\nconst WILDCARD_REGEXP_PART = '([a-zA-Z0-9-]{1,63})'\nconst WILDCARD_REGEXP_PART_ESCAPED = _escapeRegexp(WILDCARD_REGEXP_PART)\n\ntype URLCache = Map<string, URL>\ntype RegExpCache = Map<string, RegExp>\n\nimport { isIP, isLocalhost, isSpecial } from './ip'\n\nexport function isSafeUrl (url: unknown): boolean {\n if (!url || typeof url !== 'string') return false\n \n let decodedUrl: string\n try {\n decodedUrl = decodeURI(url)\n } catch (error) {\n // If decodeURI fails, treat as unsafe\n return false\n }\n\n // ReDoS-safe approach: normalize the string first, then use simple regex\n // Remove all control characters and whitespace, then check for javascript:\n const normalizedUrl = decodedUrl\n // eslint-disable-next-line no-control-regex\n .replace(/[\\u0000-\\u001F\\s]/g, '') // Remove control chars and whitespace\n .toLowerCase()\n \n return !normalizedUrl.includes('javascript:')\n}\n\nexport function replaceDomainPrefix (originalUrl: string, prefix: string): string {\n const url = new URL(originalUrl)\n\n const originalHostnameParts = url.hostname.split('.')\n const suffixParts = originalHostnameParts.length > 2 ? originalHostnameParts.slice(1) : originalHostnameParts\n const suffix = suffixParts.join('.')\n\n url.hostname = `${prefix}.${suffix}`\n\n return url.toString()\n}\n\nfunction _escapeRegexp (source: string) {\n return source.replace(REGEXP_ESCAPE_CHARS, '\\\\$&')\n}\n\nexport type ReplaceDomainOptions = { encoded?: boolean, urlsCache?: URLCache, regexpsCache?: RegExpCache }\n\nfunction _getUrl (strUrl: string, cache?: URLCache): URL {\n if (!cache) return new URL(strUrl)\n\n let parsed = cache.get(strUrl)\n if (!parsed) {\n parsed = new URL(strUrl)\n cache.set(strUrl, parsed)\n }\n return parsed\n}\n\n/** NOTE: Don't use it outside of this file, since it mutates lastIndex */\nfunction _getCachedRegexp (pattern: string, cache?: RegExpCache): RegExp {\n // NOTE: no user input here\n // nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp\n if (!cache) return new RegExp(pattern, 'g')\n\n let re = cache.get(pattern)\n if (!re) {\n // NOTE: no user input here\n // nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp\n re = new RegExp(pattern, 'g')\n cache.set(pattern, re)\n }\n re.lastIndex = 0\n return re\n}\n\nexport function getWildcardDomain (domain: string, cache?: URLCache) {\n const url = _getUrl(domain, cache)\n const [prefix, ...rest] = url.hostname.split('.')\n const port = url.port ? `:${url.port}` : ''\n return {\n wildcardDomain: `${url.protocol}//*.${rest.join('.')}${port}`,\n prefix,\n }\n}\n\nexport function replaceDomain (source: string, from: string, to: string, options: ReplaceDomainOptions = {}): string {\n const { encoded = false, urlsCache, regexpsCache } = options\n\n const fromUrl = _getUrl(from, urlsCache)\n // NOTE: URL parser encodes * as %2A in some browsers (Chromium), so decode the hostname to check for wildcards\n const decodedHostname = decodeURIComponent(fromUrl.hostname)\n\n // NOTE: for non-wildcard domain just do simple replace\n if (!decodedHostname.startsWith('*.')) {\n // Add negative lookahead to ensure domain boundary\n // Not followed by: dot+domain chars, or domain chars directly\n const escapedFrom = _escapeRegexp(from)\n const fromWithBoundary = `${escapedFrom}(?!\\\\.${WILDCARD_REGEXP_PART}|${WILDCARD_REGEXP_PART})`\n const fromSearch = _getCachedRegexp(fromWithBoundary, regexpsCache)\n let replaced = source.replace(fromSearch, to)\n\n if (encoded) {\n const fromEncoded = encodeURIComponent(from)\n const escapedFromEncoded = _escapeRegexp(fromEncoded)\n // For encoded: not followed by %2E+domain chars or domain chars directly\n const fromEncodedWithBoundary = `${escapedFromEncoded}(?!%2E${WILDCARD_REGEXP_PART}|${WILDCARD_REGEXP_PART})`\n const fromEncodedSearch = _getCachedRegexp(fromEncodedWithBoundary, regexpsCache)\n replaced = replaced.replace(fromEncodedSearch, encodeURIComponent(to))\n }\n\n return replaced\n }\n\n // NOTE: need to apply some magic on wildcards\n // NOTE: only first * is needed\n // nosemgrep: javascript.lang.security.audit.incomplete-sanitization.incomplete-sanitization\n const fromPattern = from.replace('*', WILDCARD_REGEXP_PART)\n // NOTE: only first * is needed\n // nosemgrep: javascript.lang.security.audit.incomplete-sanitization.incomplete-sanitization\n const toPattern = to.replace('*', '$1')\n\n const escapedFrom = _escapeRegexp(fromPattern).replace(WILDCARD_REGEXP_PART_ESCAPED, WILDCARD_REGEXP_PART)\n // Add negative lookahead to ensure domain boundary\n const fromWithBoundary = `${escapedFrom}(?!\\\\.${WILDCARD_REGEXP_PART}|${WILDCARD_REGEXP_PART})`\n const fromSearch = _getCachedRegexp(fromWithBoundary, regexpsCache)\n\n let replaced = source.replace(fromSearch, toPattern)\n\n if (encoded) {\n // NOTE: only first * is needed\n // nosemgrep: javascript.lang.security.audit.incomplete-sanitization.incomplete-sanitization\n const fromEncoded = encodeURIComponent(from).replace('*', WILDCARD_REGEXP_PART)\n // NOTE: only first * is needed\n // nosemgrep: javascript.lang.security.audit.incomplete-sanitization.incomplete-sanitization\n const toEncoded = encodeURIComponent(to).replace('*', '$1')\n\n const escapedFromEncoded = _escapeRegexp(fromEncoded).replace(WILDCARD_REGEXP_PART_ESCAPED, WILDCARD_REGEXP_PART)\n // For encoded: not followed by %2E+domain chars or domain chars directly\n const fromEncodedWithBoundary = `${escapedFromEncoded}(?!%2E${WILDCARD_REGEXP_PART}|${WILDCARD_REGEXP_PART})` \n const fromEncodedSearch = _getCachedRegexp(fromEncodedWithBoundary, regexpsCache)\n\n replaced = replaced.replace(fromEncodedSearch, toEncoded)\n }\n\n return replaced\n}\n\ntype URLWithMeta = Readonly<URL> & {\n isIP: boolean\n isSpecialIP: boolean\n isLocalhost: boolean\n}\n\nexport function getUrlMeta (url: string): URLWithMeta | null {\n try {\n const u: URLWithMeta = new URL(url) as URLWithMeta\n const hostnameUnWrapped = (u.hostname.startsWith('[') && u.hostname.endsWith(']'))\n ? u.hostname.slice(1, -1)\n : u.hostname\n u.isIP = isIP(hostnameUnWrapped) > 0\n u.isSpecialIP = u.isIP && isSpecial(hostnameUnWrapped)\n u.isLocalhost = u.hostname === 'localhost' || (u.isIP && isLocalhost(hostnameUnWrapped))\n\n return u\n } catch {\n return null\n }\n}\n","import { randomBytes } from 'crypto'\n\n/**\n * Generates v4 UUIDs in both browser and Node environments\n * @example\n * const uuid = generateUUIDv4()\n */\nexport function generateUUIDv4 (): string {\n let randomValues: Uint8Array\n\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n // Browser or Node.js (if Node 19+ supports crypto.randomUUID)\n return crypto.randomUUID()\n } else if (typeof window !== 'undefined' && window.crypto && window.crypto.getRandomValues) {\n // Browser environment\n randomValues = new Uint8Array(16)\n window.crypto.getRandomValues(randomValues)\n } else {\n // Node.js environment\n randomValues = randomBytes(16)\n }\n\n // Setting the version (4) and variant (RFC4122)\n randomValues[6] = (randomValues[6] & 0x0f) | 0x40 // version 4\n randomValues[8] = (randomValues[8] & 0x3f) | 0x80 // variant\n\n return [...randomValues]\n .map((value, index) => {\n const hex = value.toString(16).padStart(2, '0')\n if (index === 4 || index === 6 || index === 8 || index === 10) {\n return `-${hex}`\n }\n return hex\n })\n .join('')\n}\n","import { z } from 'zod'\n\nimport type { EventParams, ParamsValidator, RegisteredMiddleware, HandlerResult } from './types'\n\ntype TypeChecker<T extends EventParams> = (params: unknown) => params is T\n\nexport function typeCheckerToValidator<T extends EventParams> (typeChecker: TypeChecker<T>): ParamsValidator<T> {\n return (params: unknown) => {\n if (!typeChecker(params)) {\n return { success: false, error: 'Invalid params' }\n }\n\n return { success: true, data: params }\n }\n}\n\nexport function zodSchemaToValidator<T extends EventParams> (schema: z.ZodSchema<T>): ParamsValidator<T> {\n return (params: unknown) => {\n const result = schema.safeParse(params)\n if (!result.success) {\n return { success: false, error: z.prettifyError(result.error) }\n }\n\n return { success: true, data: result.data }\n }\n}\n\n/**\n * Sorts the middlewares array based on the following criteria:\n * 1. Sort by order (lower to higher)\n * 2. Non-global scope first (scope !== '*')\n * 3. Specified eventName first\n * 4. Specified eventType first\n * If first, means the middleware will be executed first and will have control of all next middlewares args / return types\n * @param middlewares\n */\nexport function sortedMiddlewares (middlewares: Array<RegisteredMiddleware<EventParams, HandlerResult>>): Array<RegisteredMiddleware<EventParams, HandlerResult>> {\n return middlewares.sort((a, b) => {\n // 1. Sort by order (lower to higher)\n const orderDiff = (a.order || 0) - (b.order || 0)\n if (orderDiff !== 0) return orderDiff\n\n // 2. Global scope should be outside (first)\n const aIsGlobal = a.scope === '*' ? 1 : 0\n const bIsGlobal = b.scope === '*' ? 1 : 0\n if (aIsGlobal !== bIsGlobal) return aIsGlobal - bIsGlobal\n\n // 3. Specified eventName should be inside (last)\n const aHasEventName = a.eventName ? 0 : 1\n const bHasEventName = b.eventName ? 0 : 1\n if (aHasEventName !== bHasEventName) return bHasEventName - aHasEventName\n\n // 4. Specified eventType should be inside (last)\n const aHasEventType = a.eventType ? 0 : 1\n const bHasEventType = b.eventType ? 0 : 1\n return bHasEventType - aHasEventType\n })\n}\n\nexport function isServiceWorker (source: unknown): source is ServiceWorker {\n return (typeof ServiceWorker !== 'undefined' && source instanceof ServiceWorker)\n}\n\ntype ResponseMessageArgs = {\n data: unknown\n target: Window | ServiceWorker\n origin: string\n}\n\nexport function sendResponseMessage ({ data, target, origin }: ResponseMessageArgs){\n if (isServiceWorker(target)) {\n target.postMessage(data)\n } else {\n target.postMessage(data, origin)\n }\n}"],"mappings":"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","names":["z","z","z","z","_a","_b"]}