### Install and Run Example Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/examples/example-graphql-upload-nextjs/README.md Clone the repository, navigate to the example directory, install dependencies, and start the development server. ```bash git clone https://github.com/lafittemehdy/graphql-upload-nextjs.git cd graphql-upload-nextjs/examples/example-graphql-upload-nextjs npm install npm run dev ``` -------------------------------- ### Migrate from graphql-upload to graphql-upload-nextjs Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md This example shows the difference in setup between the older graphql-upload with Express and the new graphql-upload-nextjs for Next.js App Router. ```typescript import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs' app.use(graphqlUploadExpress()) ``` ```typescript import { GraphQLUpload, uploadProcess } from 'graphql-upload-nextjs' // In your route handler: if (request.headers.get("content-type")?.includes("multipart/form-data")) { return await uploadProcess(request, context, server); } ``` -------------------------------- ### Install and Build Project Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Clone the repository, install dependencies, build the project, and run tests. ```bash git clone https://github.com/lafittemehdy/graphql-upload-nextjs.git cd graphql-upload-nextjs npm install npm run build npm test ``` -------------------------------- ### Install graphql-upload-nextjs Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Use npm to install the graphql-upload-nextjs package. ```bash npm install graphql-upload-nextjs ``` -------------------------------- ### GraphQL Upload Configuration Options Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Demonstrates how to configure upload limits for file type, number of files, and maximum file size. These options are passed to the `uploadProcess` function to enforce constraints on uploads, returning a 413 error if exceeded. ```typescript await uploadProcess(request, context, server, { allowedTypes: ["image/jpeg", "image/png", "text/plain"], maxFiles: 10, maxFileSize: 10 * 1024 * 1024, // 10MB }); ``` -------------------------------- ### Configuration Options for `uploadProcess` Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Provides configuration options to customize the file upload process, including allowed file types, maximum number of files, and maximum file size. ```APIDOC ## Configuration Options for `uploadProcess` ### Description Provides configuration options to customize the file upload process, including allowed file types, maximum number of files, and maximum file size. ### Options - **`allowedTypes`** (`string[]`, optional) - Description: Restricts MIME types. Verified via magic bytes. - Example: `["image/jpeg", "image/png", "text/plain"]` - **`maxFiles`** (`number`, optional) - Description: Maximum number of files per request. Returns 413 if exceeded. - Example: `10` - **`maxFileSize`** (`number`, optional) - Description: Maximum file size in bytes. Returns 413 if exceeded. - Example: `10485760` (10MB) ``` -------------------------------- ### Client-Side File Upload Mutation with Apollo Client Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Shows how to use Apollo Client's `useMutation` hook to handle file uploads from an HTML file input element. The file is automatically formatted for the GraphQL mutation as per the specification. ```typescript import { gql, useMutation } from '@apollo/client'; const UPLOAD = gql` mutation UploadFile($file: Upload!) { uploadFile(file: $file) { filename mimetype fileSize } } `; function Uploader() { const [upload] = useMutation(UPLOAD); return { const file = e.target.files?.[0]; if (file) upload({ variables: { file } }); }} />; } ``` -------------------------------- ### Core Exports Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md These are the main exports provided by the library for integrating GraphQL file uploads. ```APIDOC ## GraphQLUpload ### Description The `GraphQLUpload` scalar type is used in your GraphQL schema to define file upload fields. ### Type `GraphQLScalarType` ``` ```APIDOC ## uploadProcess ### Description This function processes incoming multipart requests that contain file uploads, preparing them for GraphQL resolvers. ### Type `function` ``` ```APIDOC ## Upload ### Description The `Upload` class is used internally to hold a promise that resolves with the details of a file upload. ### Type `class` ``` -------------------------------- ### Utility Exports Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Helper functions provided by the library for common tasks related to file uploads and data manipulation. ```APIDOC ## bufferToStream ### Description Converts a Node.js Buffer into a Node.js readable stream. ### Parameters - **`buffer`** (`Buffer`) - The buffer to convert. ### Returns `ReadableStream` ``` ```APIDOC ## parseOperationsJSON ### Description Parses the `operations` field from a multipart request. This field can be a single JSON object or an array for batching. ### Parameters - **`input`** (`string`) - The JSON string from the `operations` field. ### Returns `object | object[]` ``` ```APIDOC ## sanitizeAndValidateJSON ### Description Parses a JSON string and validates that it is a non-null, non-array object. ### Parameters - **`input`** (`string`) - The JSON string to parse and validate. ### Returns `object` ``` ```APIDOC ## setValueAtPath ### Description Sets a value at a specified dot-notation path within a nested object. ### Parameters - **`obj`** (`object`) - The object to modify. - **`path`** (`string`) - The dot-notation path to the property. - **`value`** (`any`) - The value to set. ### Returns `void` ``` ```APIDOC ## streamToBuffer ### Description Collects the contents of a readable stream into a Node.js Buffer. ### Parameters - **`stream`** (`ReadableStream`) - The readable stream to collect. ### Returns `Promise` ``` ```APIDOC ## validateMap ### Description Validates the `map` field from a multipart request, ensuring each entry is an array of string paths. ### Parameters - **`map`** (`object`) - The map object to validate. ### Returns `string | null` - Returns an error message string if validation fails, otherwise `null`. ``` -------------------------------- ### GraphQL Schema and Resolvers for File Uploads Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Defines the GraphQL schema for file uploads and implements the corresponding resolvers for handling single and multiple file uploads. Ensure filenames are sanitized to prevent path traversal attacks. Avoid writing uploaded files to publicly accessible directories in production. ```typescript import path from 'node:path' import { createWriteStream } from 'node:fs' import { pipeline } from 'node:stream' import { gql } from '@apollo/client' // Optional: syntax highlighting only. import { ApolloServer } from '@apollo/server' import { startServerAndCreateNextHandler } from '@as-integrations/next' import { type File, GraphQLUpload, uploadProcess } from 'graphql-upload-nextjs' import type { NextRequest } from 'next/server.js' const typeDefs = gql` scalar Upload type File { encoding: String! filename: String! fileSize: Int! mimetype: String! uri: String! } type Query { default: Boolean! } type Mutation { uploadFile(file: Upload!): File! uploadFiles(files: [Upload!]!): [File!]! } ` interface FileResponse { encoding: string; filename: string; fileSize: number; mimetype: string; uri: string; } const resolvers = { Mutation: { uploadFile: async ( _parent: undefined, { file }: { file: Promise }, ): Promise => { const { createReadStream, encoding, filename, fileSize, mimetype } = await file; const safeName = path.basename(filename); return new Promise((resolve, reject) => { pipeline( createReadStream(), createWriteStream(`./uploads/${safeName}`), (error) => { if (error) reject(new Error("Error during file upload.")); else resolve({ encoding, filename: safeName, fileSize, mimetype, uri: `/${safeName}` }); }, ); }); }, uploadFiles: async ( _parent: undefined, { files }: { files: Promise[] }, ): Promise => { const resolvedFiles = await Promise.all(files); return Promise.all(resolvedFiles.map(async ({ createReadStream, encoding, filename, fileSize, mimetype }) => { const safeName = path.basename(filename); return new Promise((resolve, reject) => { pipeline( createReadStream(), createWriteStream(`./uploads/${safeName}`), (error) => { if (error) reject(new Error(`Error during upload of ${safeName}.`)); else resolve({ encoding, filename: safeName, fileSize, mimetype, uri: `/${safeName}` }); }, ); }); })); }, }, Query: { default: async () => true }, Upload: GraphQLUpload, } ``` -------------------------------- ### File Object Properties Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Details about the structure of the file object passed to GraphQL resolvers after processing. ```APIDOC ## File Object ### Description The resolved file object passed to resolvers contains the following properties: - **`createReadStream`** (`() => ReadableStream`) - Creates a Node.js readable stream of the file contents. This stream is replayable. - **`encoding`** (`string`) - The transfer encoding of the file. Typically `'binary'` when using the FormData API. - **`filename`** (`string`) - The original name of the file as provided by the client. - **`fileSize`** (`number`) - The size of the file in bytes. - **`mimetype`** (`string`) - The MIME type of the file, verified using magic bytes. ``` -------------------------------- ### GraphQL Mutation for Multiple File Upload Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/examples/example-graphql-upload-nextjs/README.md Define a GraphQL mutation to upload multiple files. The input is an array of the `Upload` scalar type. ```graphql mutation UploadFiles($files: [Upload!]!) { uploadFiles(files: $files) { encoding filename fileSize mimetype uri } } ``` -------------------------------- ### Route Handler for GraphQL Uploads Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md The route handler integrates Apollo Server with Next.js, enabling it to process both standard GraphQL requests and multipart/form-data requests for file uploads. ```APIDOC ## Route Handler for GraphQL Uploads ### Description The route handler integrates Apollo Server with Next.js, enabling it to process both standard GraphQL requests and multipart/form-data requests for file uploads. ### Methods - GET - POST - OPTIONS ### Endpoint `/api/graphql` (Assumed based on Next.js conventions) ### Request Handling - If the `content-type` header includes `multipart/form-data`, the `uploadProcess` function is used to handle the file upload. - Otherwise, the standard Apollo Server handler is used. ### Context The request context includes `ip` and the original `req` object. ``` -------------------------------- ### GraphQL Mutations for File Upload Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Defines the GraphQL mutations for uploading single and multiple files. The `uploadFile` mutation accepts a single `Upload` scalar and returns a `File` object. The `uploadFiles` mutation accepts an array of `Upload` scalars and returns an array of `File` objects. ```APIDOC ## GraphQL Mutations for File Upload ### Description Defines the GraphQL mutations for uploading single and multiple files. The `uploadFile` mutation accepts a single `Upload` scalar and returns a `File` object. The `uploadFiles` mutation accepts an array of `Upload` scalars and returns an array of `File` objects. ### Mutation `uploadFile` - **Description**: Uploads a single file. - **Parameters**: - `file` (Upload!) - Required - The file to upload. - **Returns**: `File` - Information about the uploaded file. ### Mutation `uploadFiles` - **Description**: Uploads multiple files. - **Parameters**: - `files` ([Upload!]!) - Required - An array of files to upload. - **Returns**: `[File!]` - An array of information about the uploaded files. ``` -------------------------------- ### Next.js Route Handler for GraphQL Uploads Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Configures a Next.js route handler to manage incoming requests, distinguishing between standard GraphQL requests and multipart/form-data requests for file uploads. This handler integrates with Apollo Server and the graphql-upload-nextjs library. ```typescript const server = new ApolloServer({ resolvers, typeDefs }); const handler = startServerAndCreateNextHandler(server, { context: async (req: NextRequest) => ({ ip: req.headers.get("x-forwarded-for") || "", req, }), }); const requestHandler = async (request: NextRequest) => { if (request.headers.get("content-type")?.includes("multipart/form-data")) { const context = { ip: request.headers.get("x-forwarded-for") || "", req: request }; return await uploadProcess(request, context, server); } return handler(request); }; export const GET = requestHandler; export const POST = requestHandler; export const OPTIONS = requestHandler; ``` -------------------------------- ### Multiple File Upload Mutation Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/examples/example-graphql-upload-nextjs/README.md This GraphQL mutation allows for the upload of multiple files simultaneously. It returns details for each uploaded file. ```APIDOC ## Multiple File Upload ### Description Allows for the upload of multiple files. ### Method `mutation` ### GraphQL Operation `UploadFiles` ### Parameters #### Variable - **files** ([Upload!]!) - Required - An array of files to upload. ### Response #### Success Response - **uploadFiles** (Array) - Details of the uploaded files. - **encoding** (String) - **filename** (String) - **fileSize** (Int) - **mimetype** (String) - **uri** (String) ### Request Example ```graphql mutation UploadFiles($files: [Upload!]!) { uploadFiles(files: $files) { encoding filename fileSize mimetype uri } } ``` ``` -------------------------------- ### GraphQL Mutation for Single File Upload Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/examples/example-graphql-upload-nextjs/README.md Define a GraphQL mutation to upload a single file. The `Upload` scalar type is used for the file input. ```graphql mutation UploadFile($file: Upload!) { uploadFile(file: $file) { encoding filename fileSize mimetype uri } } ``` -------------------------------- ### Single File Upload Mutation Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/examples/example-graphql-upload-nextjs/README.md This GraphQL mutation allows for the upload of a single file. It returns details about the uploaded file. ```APIDOC ## Single File Upload ### Description Allows for the upload of a single file. ### Method `mutation` ### GraphQL Operation `UploadFile` ### Parameters #### Variable - **file** (Upload!) - Required - The file to upload. ### Response #### Success Response - **uploadFile** (object) - Details of the uploaded file. - **encoding** (String) - **filename** (String) - **fileSize** (Int) - **mimetype** (String) - **uri** (String) ### Request Example ```graphql mutation UploadFile($file: Upload!) { uploadFile(file: $file) { encoding filename fileSize mimetype uri } } ``` ``` -------------------------------- ### TypeScript Interfaces Source: https://github.com/lafittemehdy/graphql-upload-nextjs/blob/main/README.md Key TypeScript interfaces used within the library for type safety and clarity. ```APIDOC ## File Interface ### Description Represents the resolved file object available in GraphQL resolvers. Includes properties like `filename`, `mimetype`, `encoding`, `fileSize`, and `createReadStream`. ### Type `File` ``` ```APIDOC ## FileStream Interface ### Description Represents a file entry within a FormData object that has a `stream()` method for accessing its content. ### Type `FileStream` ``` ```APIDOC ## FormDataFile Interface ### Description Represents a raw file entry as received from a multipart FormData request. ### Type `FormDataFile` ``` ```APIDOC ## MinimalRequest Interface ### Description An interface defining a minimal request object compatible with both Next.js and standard Web API request objects. ### Type `MinimalRequest` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.