{"id":18600806,"url":"https://github.com/octet-stream/object-to-form-data","last_synced_at":"2025-08-30T16:36:13.828Z","repository":{"id":51310389,"uuid":"106339154","full_name":"octet-stream/object-to-form-data","owner":"octet-stream","description":"Transform an object/collection to FormData.","archived":false,"fork":false,"pushed_at":"2024-12-10T11:02:31.000Z","size":860,"stargazers_count":6,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-22T15:16:30.755Z","etag":null,"topics":["bracket-notation","commonjs","dot-notation","esm","form-data","javascipt","javascript-library","object-to-form-data","serialization","serialize","transform","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@octetstream/object-to-form-data","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/octet-stream.png","metadata":{"files":{"readme":"readme.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-10-09T21:52:24.000Z","updated_at":"2025-06-05T17:15:06.000Z","dependencies_parsed_at":"2025-04-10T18:42:33.367Z","dependency_job_id":"036ca922-2b14-40b4-a425-1c0bd463cf9f","html_url":"https://github.com/octet-stream/object-to-form-data","commit_stats":{"total_commits":85,"total_committers":2,"mean_commits":42.5,"dds":0.09411764705882353,"last_synced_commit":"073326d5e49a2aba7c7cb30f558e0b8dce911f83"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/octet-stream/object-to-form-data","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/octet-stream%2Fobject-to-form-data","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/octet-stream%2Fobject-to-form-data/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/octet-stream%2Fobject-to-form-data/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/octet-stream%2Fobject-to-form-data/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/octet-stream","download_url":"https://codeload.github.com/octet-stream/object-to-form-data/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/octet-stream%2Fobject-to-form-data/sbom","scorecard":{"id":701671,"data":{"date":"2025-08-11","repo":{"name":"github.com/octet-stream/object-to-form-data","commit":"0bd12d02778a702899ece2edbe62f7e033071319"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/20 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:39: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:63: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/typescript.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/typescript.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/typescript.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/typescript.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/typescript.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/typescript.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/typescript.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/octet-stream/object-to-form-data/typescript.yml/main?enable=pin","Info:   0 out of   9 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   5 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/release.yml:1","Warn: no topLevel permission defined: .github/workflows/typescript.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: license:0","Info: FSF or OSI recognized license: MIT License: license:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 10 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"11 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-3mv9-4h5g-vhg3"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T05:20:57.152Z","repository_id":51310389,"created_at":"2025-08-22T05:20:57.152Z","updated_at":"2025-08-22T05:20:57.152Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272878210,"owners_count":25008340,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-30T02:00:09.474Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bracket-notation","commonjs","dot-notation","esm","form-data","javascipt","javascript-library","object-to-form-data","serialization","serialize","transform","typescript"],"created_at":"2024-11-07T02:05:42.662Z","updated_at":"2025-08-30T16:36:13.785Z","avatar_url":"https://github.com/octet-stream.png","language":"TypeScript","readme":"# object-to-form-data\n\nSerialize objects, arrays and collections into [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData).\n\n[![Code Coverage](https://codecov.io/github/octet-stream/object-to-form-data/coverage.svg?branch=master)](https://codecov.io/github/octet-stream/object-to-form-data?branch=master)\n[![CI](https://github.com/octet-stream/object-to-form-data/workflows/CI/badge.svg)](https://github.com/octet-stream/object-to-form-data/actions/workflows/ci.yml)\n\n## Installation\n\npnpm:\n\n```sh\npnpm add @octetstream/object-to-form-data\n```\n\nnpm:\n```sh\nnpm i @octetstream/object-to-form-data\n```\n\n## CJS/ESM support\n\nThis module supports both CommonJS and ES Modules.\n\n## Usage\n\n1. To use this package, just import `objectToFormData` and pass `input` data as the first argument:\n\n```ts\nimport {objectToFormData} from \"@octetstream/object-to-form-data\"\n\nconst user = {\n  name: \"The Octocat\",\n  login: \"octocat\",\n  url: \"https://github.com/octocat\",\n  repositories: {\n    nodes: [\n      {\n        name: \"Hello-World\",\n        description: \"My first repository on GitHub!\",\n        url: \"https://github.com/octocat/Hello-World\"\n      }\n    ]\n  }\n}\n\n// You will receive a FormData instance with all fields of given object\nconst form = objectToFormData(user)\n\nconst options = {\n  method: \"post\",\n  body: form\n}\n\nconst response = await fetch(\"https://httpbin.org/post\", options)\n```\n\nThe `user` object from this example will be serailized into FormData with following structure (pseudo code):\n\n```\nname = \"The Octocat\"\nlogin = \"octocat\"\nurl = \"https://github.com/octocat\"\nrepositories[nodes][0][name] = \"Hello-World\"\nrepositories[nodes][0][description] = \"My first repository on GitHub!\"\nrepositories[nodes][0][url] = \"https://github.com/octocat/Hello-World\"\n```\n\n2. By default the `bracked` notation is applied, but use can pass `dot` as `notation` option like this:\n\n```ts\nimport {objectToFormData} from \"@octetstream/object-to-form-data\"\n\nconst person = {\n  name: \"Nick K.\",\n  url: \"https://github.com/octet-stream\",\n  skills: [\"TypeScript\", \"JavaScript\", \"React\", \"Next.js\", \"Vue\", \"Nuxt\", \"Qwik\", \"Docker\"]\n}\n\nconst form = objectToFormData(person, {\n  notation: \"dot\" // This will enable dot notation for serialization\n})\n```\n\nReturned `form` object has following structure:\n\n```\nname = \"Nick K.\"\nurl = \"https://github.com/octet-stream\"\nskills.0 = TypeScript\nskills.1 = JavaScript\nskills.2 = React\nskills.3 = Next.js\nskills.4 = Vue\nskills.5 = Nuxt\nskills.6 = Qwik\nskills.7 = Docker\n```\n\n3. You can also pass collections as the input:\n\n```ts\nimport {objectToFormData} from \"@octetstream/object-to-form-data\"\n\nconst developers = [\n  {\n    name: \"John Doe\",\n    skills: [\"JavaScript\", \"TypeScript\", \"React\", \"Qwik\"],\n    isHireable: true\n  },\n  {\n    name: \"Max Doe\",\n    skills: [\"Python\", \"Django\", \"Flask\", \"MySQL\", \"Pony ORM\"],\n    isHireable: false\n  }\n]\n\nconst form = objectToFormData(developers)\n```\n\nThis results in following `form` structure:\n\n```\n[0][name] = \"John Doe\"\n[0][skills][0] = \"JavaScript\"\n[0][skills][1] = \"TypeScript\"\n[0][skills][2] = \"React\"\n[0][skills][3] = \"Qwik\"\n[1][name] = \"Max Doe\"\n[1][skills][0] = \"Python\"\n[1][skills][1] = \"Django\"\n[1][skills][2] = \"Flask\"\n[1][skills][3] = \"MySQL\"\n[1][skills][4] = \"Pony ORM\"\n```\n\n4. Flat arrays supported too:\n\n```ts\nimport {objectToFormData} from \"@octetstream/object-to-form-data\"\n\nconst fruits = [\"orange\", \"pineapple\", \"nectarine\", \"pear\", \"pomegranate\"]\n\nconst form = objectToFormData(fruits)\n```\n\nResult:\n\n```\n[0] = \"orange\"\n[1] = \"pineapple\"\n[2] = \"nectarine\"\n[3] = \"pear\"\n[4] = \"pomegranate\"\n```\n\n5. Serializing files and blobs:\n\n```ts\nimport {objectToFormData} from \"@octetstream/object-to-form-data\"\n\nconst input = [\n  {\n    caption: \"Text file created with File object\",\n    file: new File([\"My hovercraft if full of eels\"], \"test.txt\", {type: \"text/plain\"}),\n  },\n  {\n    caption: \"Text data created with Blob object\",\n    file: new Blob([\"On Soviet Moon landscape see binoculars through you\"], {type: \"text/plain\"}),\n  }\n]\n\nconst form = objectToFormData(input)\n```\n\nResult:\n\n```\n[0][caption] = \"Text file created with File object\"\n[0][file] = File [type: \"text/plain\", name: \"test.txt\", content: \"My hovercraft if full of eels\"]\n[1][caption] = \"Text data created with Blob object\"\n[1][file] = File [type: \"text/plain\", name: \"blob\", content: \"On Soviet Moon landscape see binoculars through you\"]\n```\n\n## API\n\n### `objectToFormData(input[, options]): FormData`\n\nSerializes objects, arrays and collections into `FormData`.\n\nNested objects will be flattened using either dot or bracket notation.\n\nThis function takes following arguments:\n\n| Name    | Type                                                            | Required  | Default     | Description                      |\n|---------|:---------------------------------------------------------------:|:---------:|:-----------:|----------------------------------|\n| input   | `unknown[] \\| Record\u003csting \\| number, unknown\u003e`                 | true      | –           | An object to transform           |\n| options | [`ObjectToFormDataOptions`](#interface-objecttoformdataoptions) | false     | `undefined` | Additional serialization options |\n\nReturns `FormData` instance.\n\n### `interface ObjectToFormDataOptions`\n\nSerialization options\n\n| Name           | Type                                     | Required | Default               | Description                                                                                                   |\n|----------------|:----------------------------------------:|:--------:|:---------------------:|---------------------------------------------------------------------------------------------------------------|\n| strict         | `boolean`                                | false    | `false`               | Indicates whether or not to omit every `false` values. Applied enabled. Does not affect boolean array values  |\n| FormData       | `FormData`                               | false    | `globalThis.FormData` | Custom spec-compliant [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) implementation  |\n| notation       | `\"dot\" \\| \"bracket\"`                     | false    | `\"bracket\"`           | Type of the nested fields notation. Can be either `\"dot\"` or `\"bracket\"`                                      |\n| normalizeValue | [`NormalizeValue`](#type-normalizevalue) | false    | `undefined`           | Value normalizer. This function will be called on each *scalar* value, before it's added to FormData instance |\n\n### `interface NormalizeValue`\n\nValue normalizer.\n\nA function to be called on each *scalar* value, before it's added to FormData instance. It **must** return either `Blob` or `string`\n\nThis function will be called with the following arguments:\n\n| Name    | Type                      | Description                         |\n|---------|:-------------------------:|-------------------------------------|\n| value   | `unknown`                 | Current entry value                 |\n| name    | `string`                  | The name of the entry               |\n| path    | `Array\u003cstring \\| number\u003e` | Entry's path within original object |\n\nThis function **must** return either `Blob` or `string`. Any unsupported type will be converted to string by `FormData`.\n\n## Related links\n\n- [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) documentation on MDN\n- [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) documentation on MDN\n- [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) documentation on MDN\n- [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue) documentation on MDN.\n- [`formdata-node`](https://github.com/octet-stream/form-data) Spec-compliant `FormData` implementation for Node.js.\n- [`formdata-polyfill`](https://github.com/jimmywarting/FormData) HTML5 `FormData` for Browsers \u0026 NodeJS.\n- [`node-fetch`](https://github.com/node-fetch/node-fetch) a light-weight module that brings the Fetch API to Node.js\n- [`fetch-blob`](https://github.com/node-fetch/fetch-blob) a Blob implementation for Node.js, originally from `node-fetch`.\n- [`form-data-encoder`](https://github.com/octet-stream/form-data-encoder) spec-compliant `multipart/form-data` encoder implementation.\n- [`then-busboy`](https://github.com/octet-stream/then-busboy) a promise-based wrapper around Busboy. Process `multipart/form-data` content and returns it as a single object. Will be helpful to handle your data on the server-side applications.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foctet-stream%2Fobject-to-form-data","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foctet-stream%2Fobject-to-form-data","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foctet-stream%2Fobject-to-form-data/lists"}