UNPKG

graphql-yoga

Version:

<div align="center"><img src="https://raw.githubusercontent.com/graphql-hive/graphql-yoga/refs/heads/main/website/public/cover.png" width="720" /></div>

78 lines (77 loc) 2.76 kB
import { createGraphQLError } from '@graphql-tools/utils'; import { handleMaybePromise } from '@whatwg-node/promise-helpers'; import { isContentTypeMatch } from './utils.js'; export function isPOSTMultipartRequest(request) { return request.method === 'POST' && isContentTypeMatch(request, 'multipart/form-data'); } export function parsePOSTMultipartRequest(request) { return handleMaybePromise(() => request.formData(), (requestBody) => { const operationsStr = requestBody.get('operations'); if (!operationsStr) { throw createGraphQLError('Missing multipart form field "operations"'); } if (typeof operationsStr !== 'string') { throw createGraphQLError('Multipart form field "operations" must be a string'); } let operations; try { operations = JSON.parse(operationsStr); } catch { throw createGraphQLError('Multipart form field "operations" must be a valid JSON string'); } const mapStr = requestBody.get('map'); if (mapStr != null) { if (typeof mapStr !== 'string') { throw createGraphQLError('Multipart form field "map" must be a string'); } let map; try { map = JSON.parse(mapStr); } catch { throw createGraphQLError('Multipart form field "map" must be a valid JSON string'); } for (const fileIndex in map) { const file = requestBody.get(fileIndex); const keys = map[fileIndex]; for (const key of keys) { setObjectKeyPath(operations, key, file); } } } return operations; }, e => { if (e instanceof Error && e.message.startsWith('File size limit exceeded: ')) { throw createGraphQLError(e.message, { extensions: { http: { status: 413, }, }, }); } throw e; }); } // eslint-disable-next-line @typescript-eslint/no-explicit-any function setObjectKeyPath(object, keyPath, value) { const keys = keyPath.split('.'); let current = object; for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (key === '__proto__' || key === 'constructor' || key === 'prototype') { return; } const isLastKey = i === keys.length - 1; if (isLastKey) { current[key] = value; } else { if (!(key in current)) { current[key] = {}; } current = current[key]; } } }