UNPKG

@mridang/nestjs-auth

Version:

A comprehensive Auth.js integration for NestJS applications with TypeScript support, framework-agnostic HTTP adapters, and role-based access control

108 lines 3.62 kB
import qs from 'qs'; import { Readable } from 'node:stream'; /** * Converts a framework-specific request (Fastify or Express) into a * standard Web API `Request` object… */ export function toWebRequest(request, adapter) { const protocol = adapter.getProtocol(request); const host = adapter.getHost(request); const url = `${protocol}://${host}${adapter.getUrl(request)}`; const headers = new Headers(); const rawHeaders = adapter.getHeaders(request); Object.entries(rawHeaders).forEach(([key, value]) => { if (Array.isArray(value)) { value.forEach((v) => v && headers.append(key, v)); } else if (value) { headers.append(key, value); } }); const method = adapter.getMethod(request); const contentType = headers.get('content-type'); let body; if (!/GET|HEAD/.test(method.toUpperCase())) { const rawBody = adapter.getBody(request); if (rawBody !== undefined && rawBody !== null) { if (contentType?.includes('application/x-www-form-urlencoded')) { body = qs.stringify(rawBody, { arrayFormat: 'repeat' }); } else if (contentType?.includes('application/json')) { body = JSON.stringify(rawBody); } else if (typeof rawBody === 'string') { body = rawBody; } else if (Buffer.isBuffer(rawBody)) { body = rawBody; } else if (typeof rawBody === 'object') { // Fallback for object bodies without a proper content-type. body = qs.stringify(rawBody, { arrayFormat: 'repeat' }); } } } return new Request(url, { method, headers, body }); } /** * Maps a standard Web API `Response` object to a framework-specific response… */ export async function toHttpResponse(webResponse, res, adapter) { // Build headers without using Headers.entries() to avoid dom.iterable dependency issues. const groupedHeaders = {}; webResponse.headers.forEach((value, key) => { const lowerKey = key.toLowerCase(); if (lowerKey === 'set-cookie') { const existing = groupedHeaders[lowerKey]; if (Array.isArray(existing)) { existing.push(value); } else if (existing) { groupedHeaders[lowerKey] = [existing, value]; } else { groupedHeaders[lowerKey] = [value]; } } else { groupedHeaders[key] = value; } }); Object.entries(groupedHeaders).forEach(([key, value]) => { adapter.setHeader(res, key, value); }); adapter.setStatus(res, webResponse.status); const body = webResponse.body; if (body) { const reader = body.getReader(); const nodeStream = Readable.from((async function* () { try { while (true) { const { done, value } = await reader.read(); if (done) break; if (value) { yield Buffer.from(value); } } } finally { reader.releaseLock(); } })()); adapter.send(res, nodeStream); } else { const text = await webResponse.text(); adapter.send(res, text); } } //# sourceMappingURL=http-adapters.js.map