{"version":3,"sources":["../../src/helpers/apollo.ts","../../src/helpers/sender.ts","../../src/helpers/uuid.ts"],"sourcesContent":["import { parse as parseCookieString, serialize as serializeCookie } from 'cookie'\nimport { setCookie, getCookies } from 'cookies-next'\n\nimport {\n    FINGERPRINT_ID_COOKIE_NAME,\n    generateFingerprint,\n    getClientSideFingerprint,\n} from './sender'\nimport { generateUUIDv4 } from './uuid'\n\nimport type { DefaultContext, RequestHandler } from '@apollo/client'\nimport type { IncomingMessage, ServerResponse } from 'http'\n\ntype Response = ServerResponse\n\ntype SSRContext = {\n    headers: Record<string, string>\n}\n\nconst SSR_DEFAULT_FINGERPRINT = 'webAppSSR'\nconst COOKIE_HEADER_NAME = 'cookie'\nconst REMOTE_APP_HEADER_NAME = 'x-remote-app'\nconst REMOTE_VERSION_HEADER_NAME = 'x-remote-version'\nconst REMOTE_CLIENT_HEADER_NANE = 'x-remote-client'\nconst REMOTE_ENV_HEADER_NAME = 'x-remote-env'\nconst TARGET_HEADER_NAME = 'x-target'\nconst START_REQUEST_ID_HEADER_NAME = 'x-start-request-id'\nconst PARENT_REQUEST_ID_HEADER_NAME = 'x-parent-request-id'\n\nexport type TracingMiddlewareOptions = {\n    serviceUrl: string\n    codeVersion: string\n    target?: string\n}\n\nfunction generateRequestId () {\n    return `BR${generateUUIDv4().replaceAll('-', '')}`\n}\n\nexport function getTracingMiddleware (options: TracingMiddlewareOptions): RequestHandler {\n    return function (operation, forward) {\n        operation.setContext((previousContext: DefaultContext) => {\n            const { headers: previousHeaders } = previousContext\n\n            const reqId = generateRequestId()\n\n            const headers = {\n                ...previousHeaders,\n                [REMOTE_APP_HEADER_NAME]: options.serviceUrl,\n                [REMOTE_VERSION_HEADER_NAME]: options.codeVersion,\n                [PARENT_REQUEST_ID_HEADER_NAME]: reqId,\n                [START_REQUEST_ID_HEADER_NAME]: reqId,\n            }\n\n            if (options.target) {\n                headers[TARGET_HEADER_NAME] = options.target\n            }\n\n            headers[REMOTE_ENV_HEADER_NAME] = typeof document === 'undefined' ? 'SSR' : 'CSR'\n\n\n\n            // NOTE: CSR\n            if (typeof document !== 'undefined' && document.cookie) {\n                headers[REMOTE_CLIENT_HEADER_NANE] = getClientSideFingerprint()\n            } else if (headers[COOKIE_HEADER_NAME]) {\n                const ssrCookies = parseCookieString(headers[COOKIE_HEADER_NAME])\n\n                headers[REMOTE_CLIENT_HEADER_NANE] = ssrCookies[FINGERPRINT_ID_COOKIE_NAME] || SSR_DEFAULT_FINGERPRINT\n            }\n\n\n            return {\n                ...previousContext,\n                headers,\n            }\n        })\n\n        return forward(operation)\n    }\n}\n\nexport function prepareSSRContext (req?: IncomingMessage, res?: Response): SSRContext {\n    if (!req) {\n        return {\n            headers: {},\n        }\n    }\n\n    const requestCookies = getCookies({ req, res })\n\n    if (!requestCookies[FINGERPRINT_ID_COOKIE_NAME]) {\n        const fingerprint = generateFingerprint()\n        requestCookies[FINGERPRINT_ID_COOKIE_NAME] = fingerprint\n        // NOTE: req and res are used to operate \"set-cookie\" headers\n        setCookie(FINGERPRINT_ID_COOKIE_NAME, fingerprint, { req, res })\n    }\n\n    const cookieHeader = Object.entries(requestCookies)\n        .map(([name, value]) => value ? serializeCookie(name, value) : null)\n        .filter(Boolean)\n        .join(';')\n\n    return {\n        headers: {\n            cookie: cookieHeader,\n        },\n    }\n}\n","import { getCookie, setCookie } from 'cookies-next'\n\nimport { generateUUIDv4 } from './uuid'\n\ntype SenderInfo = {\n    dv: number\n    fingerprint: string\n}\n\n/** Name of the cookie in which the fingerprint will be stored */\nexport const FINGERPRINT_ID_COOKIE_NAME = 'fingerprint'\n/** Default fingerprint length */\nexport const FINGERPRINT_ID_LENGTH = 12\n\nfunction makeId (length: number): string {\n    const croppedLength = Math.min(length, 32)\n\n    return generateUUIDv4().replaceAll('-', '').substring(0, croppedLength)\n}\n\nexport function generateFingerprint (): string {\n    return makeId(FINGERPRINT_ID_LENGTH)\n}\n\n/**\n * Creates a device fingerprint in the browser environment\n * that can be used to send mutations in open-condo applications,\n * uses cookies for storage between sessions.\n * Mostly used to generate the sender field in getClientSideSenderInfo.\n * So consider using it instead\n */\nexport function getClientSideFingerprint (): string {\n    let fingerprint = getCookie(FINGERPRINT_ID_COOKIE_NAME)\n    if (!fingerprint) {\n        fingerprint = generateFingerprint()\n        setCookie(FINGERPRINT_ID_COOKIE_NAME, fingerprint)\n    }\n\n    return fingerprint\n}\n\n/**\n * Creates a device fingerprint in the browser environment\n * that can be used to send mutations in open-condo applications.\n * Uses cookies for storage between sessions\n * @example\n *  submitReadingsMutation({\n *     variables: {\n *         data: {\n *             ...values,\n *             dv: 1,\n *             sender: getClientSideSenderInfo(),\n *             meter: { connect: { id: meter.id } },\n *             source: { connect: { id: METER_READING_MOBILE_APP_SOURCE_ID } },\n *         },\n *     },\n * })\n */\nexport function getClientSideSenderInfo (): SenderInfo {\n    return {\n        dv: 1,\n        fingerprint: getClientSideFingerprint(),\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"],"mappings":"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","names":["setCookie","setCookie"]}