{"id":13196,"library":"form-auto-content","title":"Form Auto Content","description":"form-auto-content is a utility library designed to simplify the creation of HTTP request payloads for web applications, intelligently determining the correct `Content-Type` header and payload format. It automatically switches between `application/x-www-form-urlencoded` and `multipart/form-data` based on the input data: if JavaScript `Stream` objects or `Buffer` instances are present within the input, it defaults to `multipart/form-data` for handling file uploads; otherwise, it constructs a standard `x-www-form-urlencoded` string. The current stable version is 3.2.1, indicating active development with a release cadence that includes minor and patch updates for new features, dependency management, and bug fixes, typically released as needed rather than on a fixed schedule. A key differentiator is its robust auto-sensing capability, allowing developers to pass a single JavaScript object without explicitly specifying the `enctype`. It gracefully handles complex data structures, including nested arrays, and supports advanced file options like custom filenames and content types for `multipart` fields. This makes it particularly useful for interacting with HTTP servers, especially within Node.js environments for server-side forms or API client libraries, and it integrates well with frameworks like Fastify and testing utilities such as `light-my-request`. The library also provides an API to customize the output field names for the generated payload stream and headers object.","status":"active","version":"3.2.1","language":"javascript","source_language":"en","source_url":"https://github.com/Eomm/form-auto-content","tags":["javascript","form","form-auto-content","x-www-form-urlencoded","multipart","form-data","form-enctype","enctype","typescript"],"install":[{"cmd":"npm install form-auto-content","lang":"bash","label":"npm"},{"cmd":"yarn add form-auto-content","lang":"bash","label":"yarn"},{"cmd":"pnpm add form-auto-content","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library exports a default function. Named imports are incorrect.","wrong":"import { formAutoContent } from 'form-auto-content';","symbol":"formAutoContent","correct":"import formAutoContent from 'form-auto-content';"},{"note":"Standard CommonJS import for Node.js environments prior to ESM adoption.","symbol":"formAutoContent (CommonJS)","correct":"const formAutoContent = require('form-auto-content');"},{"note":"When providing custom output field names, use `as const` on the options object for accurate TypeScript type inference on the returned object.","symbol":"formAutoContent (TypeScript with options)","correct":"const options = { payload: 'body', headers: 'head' } as const;\nconst form = formAutoContent(data, options);"}],"quickstart":{"code":"import formAutoContent from 'form-auto-content';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { Readable } from 'stream';\n\n// Create dummy files for the example\nconst tempFilePath1 = path.join(__dirname, 'the-file.txt');\nconst tempFilePath2 = path.join(__dirname, 'foo.md');\nfs.writeFileSync(tempFilePath1, 'This is file content.');\nfs.writeFileSync(tempFilePath2, '# Hello Markdown');\n\nasync function example() {\n  // Scenario 1: x-www-form-urlencoded (no files/buffers) - auto-detected\n  const formUrlEncoded = formAutoContent({\n    field1: 'value1',\n    field2: ['value2', 'value2.2'],\n    numberField: 123,\n  });\n\n  console.log('--- URL-encoded Form ---');\n  console.log('Headers:', formUrlEncoded.headers); // Should be application/x-www-form-urlencoded\n  const urlEncodedPayload = await streamToString(formUrlEncoded.payload as Readable);\n  console.log('Payload:', urlEncodedPayload);\n  console.log('\\n');\n\n  // Scenario 2: multipart/form-data (with files/buffers) and custom output names - auto-detected\n  const options = {\n    payload: 'requestBody',\n    headers: 'requestHeaders',\n    // forceMultiPart: true // Can be uncommented to explicitly force multipart/form-data\n  } as const; // 'as const' is crucial for TypeScript to infer correct return types\n\n  const formMultiPart = formAutoContent({\n    name: 'John Doe',\n    email: 'john@example.com',\n    profilePic: fs.createReadStream(tempFilePath1),\n    document: {\n      value: fs.createReadStream(tempFilePath2),\n      options: {\n        filename: 'my-doc.md',\n        contentType: 'text/markdown'\n      }\n    },\n    items: ['item1', 'item2'],\n    jsonField: Buffer.from(JSON.stringify({ key: 'value', arr: [1, 2] })),\n  }, options);\n\n  console.log('--- Multipart Form with Custom Names ---');\n  console.log('Headers:', formMultiPart.requestHeaders); // Should be multipart/form-data\n  // In a real scenario, you would pipe formMultiPart.requestBody to an HTTP client.\n  console.log('Payload is a stream:', formMultiPart.requestBody instanceof Readable);\n  console.log('\\n');\n\n  // Clean up dummy files\n  fs.unlinkSync(tempFilePath1);\n  fs.unlinkSync(tempFilePath2);\n}\n\n// Helper function to convert a stream to string (for url-encoded example)\nfunction streamToString(stream: Readable): Promise<string> {\n  const chunks: Buffer[] = [];\n  return new Promise((resolve, reject) => {\n    stream.on('data', chunk => chunks.push(chunk));\n    stream.on('error', reject);\n    stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));\n  });\n}\n\nexample().catch(console.error);\n","lang":"typescript","description":"Demonstrates how `form-auto-content` automatically handles `x-www-form-urlencoded` and `multipart/form-data` payloads, including file streams, buffers, arrays, and custom output field names."},"warnings":[{"fix":"Upgrade your Node.js environment to version 14.0.0 or higher. For older environments, use `form-auto-content@2.x`.","message":"Version 3.0.0 introduced a breaking change by updating Node.js engine requirements to `>=14.0.0`. Users on older Node.js versions must upgrade their environment or remain on v2.x.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Thoroughly test your application when migrating from v2.x to v3.x. Refer to the GitHub changelog for specific dependency updates that might indirectly affect behavior.","message":"Major version 3.0.0 included 'deps and codebase maintenance', which may introduce subtle breaking changes beyond the stated Node.js engine bump. Always review your usage when upgrading from v2.x to v3.x.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Append `as const` to your options object, e.g., `{ payload: 'body', headers: 'head' } as const`.","message":"When using TypeScript with custom output options (e.g., `{ payload: 'body', headers: 'head' }`), you must use `as const` on the options object for correct type inference. Without it, TypeScript may not accurately narrow the return type, leading to errors when accessing the custom keys.","severity":"gotcha","affected_versions":">=3.2.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"For ESM, use `import formAutoContent from 'form-auto-content';`. For CommonJS, use `const formAutoContent = require('form-auto-content');`.","cause":"Attempting to use `formAutoContent` with an incorrect import style, such as a named import (`import { formAutoContent } from 'form-auto-content';`) or a `require` call in an ESM module context.","error":"TypeError: formAutoContent is not a function"},{"fix":"If custom keys were provided in the options, access them (e.g., `myForm.body`). Ensure the options object is declared with `as const` for accurate type inference: `const options = { payload: 'body', headers: 'head' } as const;`.","cause":"This TypeScript error occurs when custom output keys (like 'body' and 'head') are defined in the options, but the code attempts to access the default keys ('payload' and 'headers'), often without using `as const` on the options object for proper type inference.","error":"Property 'payload' does not exist on type '{ body: Stream; head: {}; }.'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}