{"id":34789721,"url":"https://github.com/remigermain/multipart-object","last_synced_at":"2026-03-27T02:09:43.951Z","repository":{"id":40534098,"uuid":"417235241","full_name":"remigermain/multipart-object","owner":"remigermain","description":"library to convert a classic object to a nested object for http 'multipart/formdata'","archived":false,"fork":false,"pushed_at":"2024-10-20T18:37:43.000Z","size":489,"stargazers_count":6,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-24T05:46:00.380Z","etag":null,"topics":["formdata","javascript","json","multipart","nested","nodejs","parser"],"latest_commit_sha":null,"homepage":"","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/remigermain.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2021-10-14T18:08:03.000Z","updated_at":"2024-12-20T15:24:00.000Z","dependencies_parsed_at":"2024-10-20T22:35:42.166Z","dependency_job_id":null,"html_url":"https://github.com/remigermain/multipart-object","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/remigermain/multipart-object","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remigermain%2Fmultipart-object","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remigermain%2Fmultipart-object/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remigermain%2Fmultipart-object/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remigermain%2Fmultipart-object/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/remigermain","download_url":"https://codeload.github.com/remigermain/multipart-object/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remigermain%2Fmultipart-object/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31009303,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-27T01:56:05.093Z","status":"online","status_checked_at":"2026-03-27T02:00:08.055Z","response_time":164,"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":["formdata","javascript","json","multipart","nested","nodejs","parser"],"created_at":"2025-12-25T09:57:11.281Z","updated_at":"2026-03-27T02:09:43.940Z","avatar_url":"https://github.com/remigermain.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Multipart-object\n\n\u003ca href=\"https://u8views.com/github/remigermain\"\u003e\u003cimg src=\"https://u8views.com/api/v1/github/profiles/66946113/views/day-week-month-total-count.svg\" width=\"1px\" height=\"1px\"\u003e\u003c/a\u003e\n[![CI](https://github.com/remigermain/multipart-object/actions/workflows/node.js.yml/badge.svg)](https://github.com/remigermain/multipart-object/actions/workflows/node.js.yml)\n[![build](https://img.shields.io/npm/v/multipart-object)](https://www.npmjs.com/package/multipart-object)\n![NPM Downloads](https://img.shields.io/npm/dm/multipart-object)\n\n\nlibrary to convert a classic object to a nested object, for send nested data in multipart http request.\nA parser for nodejs is provided.\n\n## Installation\n\n```bash\n# with yarn\nyarn add multipart-object\n# npm\nnpm install multipart-object\n```\n```html\n# cnd for nestedMultiPart function\n \u003cscript src=\"https://unpkg.com/multipart-object/dist/nestedMultiPart.js\" defer\u003e\u003c/script\u003e\n```\n\n\n\n# Convert data to nestedMultiPart\n\n### How is work\n```js\n//es module\nimport nestedMultiPart from \"multipart-object\"\n// with cdn\nconst toObject = windows.nestedMultiPart.toObject\nconst toFormData = windows.nestedMultiPart.toFormData\n\n\nconst data = {\n    key: \"value\",\n    array: [\n        \"value1\",\n        true,\n        \"value3\"\n        42,\n        {\n            anotherkey: \"value\",\n            anotherkey2: \"value2\"\n        }\n    ],\n    what: {\n        nice: \"library\"\n    }\n}\n\nconst nestedData = nestedMultiPart.toObject(data)\n// output\n{\n  \"key\": 'value',\n  'array[0]': 'value1',\n  'array[1]': true,\n  'array[2]': 'value3',\n  'array[3]': 42,\n  'array[4][anotherkey]': 'value',\n  'array[4][anotherkey2]': 'value2',\n  'what[nice]': 'library'\n}\n// you have to nestedMultiPartForm is return FormData with nested formated\nconst nestedData = nestedMultiPart.toFormData(data)\n\n```\n\n### Options\n```js\nconst options = {\n\t/*\n\t\tSeparators:\n\t\twith bracket:  article[0][title][authors][0]: \"jhon doe\"\n\t\twith dot:      article.0.title.authors.0: \"jhon doe\"\n\t\twith mixed:      article[0]title.authors[0]: \"jhon doe\"\n\t\twith mixedDot:      article[0].title.authors[0]: \"jhon doe\"\n\t*/\n\tseparator: 'bracket' or 'dot' or 'mixed' or 'mixedDot', // default is bracket\n}\n\nnestedMultiPart(data, options)\n```\n\n# Parser for multipart nested\nIf your project are mande in python, you can use this lib\n[nested_multipart_parser](https://github.com/remigermain/nested-multipart-parser)\n\nA parser made for nodeJs\n\nFor this working perfectly you need to follow this rules:\n\n\nFor this to work perfectly, you must follow the following rules:\n\n- A first key always need to be set. ex: `title[0]` or `title`. In both cases the first key is `title`\n- Each sub key need to be separate by brackets `[ ]` or dot `.` (depends of your options)\n- For `mixed` or `mixedDot` options, brackets `[]` is for list, and dot `.` is for object\n- For `mixedDot` options, is look like `mixed` but with dot when array is follow a object\n- Don't put spaces between separators.\n- By default, you can't set duplicates keys (see options)\n  \n## How it works:\n\nAttributes where sub keys are full numbers only are automatically converted into lists:\n\n```python\n\tdata = {\n\t\t'title[0]': 'my-value',\n\t\t'title[1]': 'my-second-value'\n\t}\n\toutput = {\n\t\t'title': [\n\t\t\t'my-value',\n\t\t\t'my-second-value'\n\t\t]\n\t}\n\n\t# Be aware of the fact that you have to respect the order of the indices for arrays, thus \n    \t'title[2]': 'my-value' # Invalid (you have to set title[0] and title[1] before)\n\n    # Also, you can't create an array on a key already set as a prinitive value (int, boolean or string):\n\t\t'title': 42,\n\t\t'title[object]': 42 # Invalid\n```\n\n\n\nAttributes where sub keys are other than full numbers are converted into Python dictionary:\n\n```python\n\tdata = {\n\t\t'title.key0': 'my-value',\n\t\t'title.key7': 'my-second-value'\n\t}\n\toutput = {\n\t\t'title': {\n\t\t\t'key0': 'my-value',\n\t\t\t'key7': 'my-second-value'\n\t\t}\n\t}\n    \n\n    # You have no limit for chained key:\n\t# with \"mixedDot\" separator option (same as 'mixed' but with dot after list to object):\n\tdata = {\n\t\t'the[0].chained.key[0].are.awesome[0][0]': 'im here !!'\n\t}\n\t# with \"mixed\" separator option:\n\tdata = {\n\t\t'the[0]chained.key[0]are.awesome[0][0]': 'im here !!'\n\t}\n\t# With \"bracket\" separator option:\n\tdata = {\n\t\t'the[0][chained][key][0][are][awesome][0][0]': 'im here !!'\n\t}\n\t# With \"dot\" separator option:\n\tdata = {\n\t\t'the.0.chained.key.0.are.awesome.0.0': 'im here !!'\n\t}\n```\n\n\n\n## Parser usage\n```js\nconst NestedParser = require('multipart-object')\n\n// options is optional\nconst options = {\n    separator: \"dot\"\n}\n\nconst parser = new NestedParser(data, options)\nif (parser.isValid()) {\n    const validateData = parser.validateData\n\n} else {\n    console.error(parser.errors)\n}\n```\n\n## Options\n\n```js\nconst options = {\n\t/*\n\t\tSeparators:\n\t\twith bracket:  article[0][title][authors][0]: \"jhon doe\"\n\t\twith dot:      article.0.title.authors.0: \"jhon doe\"\n\t\twith mixed:      article[0].title.authors[0]: \"jhon doe\"\n\t\twith mixedDot:      article[0]title.authors[0]: \"jhon doe\"\n\t*/\n\tseparator: 'bracket' or 'dot' or 'mixed' or 'mixedDot', // default is bracket\n\n    /*\n    raise a expections when you have duplicate keys\n\t    ex :\n\t    {\n\t\t    \"article\": 42,\n\t    \t\"article[title]\": 42,\n\t    } \n    */\n\tthrowDuplicate: true,\n\n\t/*\n    overide the duplicate keys, you need to set \"throwDuplicate\" to False\n\t ex :\n\t {\n\t\t\"article\": 42,\n\t\t\"article[title]\": 42,\n\t }\n\t the out is\n\t ex :\n\t {\n\t\t\"article\"{\n\t \t\t\"title\": 42,\n\t\t}\n\t }\n     */\n\tassignDuplicate: false\n}\n```\n\n## License\n\n[MIT](https://github.com/remigermain/multipart-object/blob/main/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremigermain%2Fmultipart-object","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fremigermain%2Fmultipart-object","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremigermain%2Fmultipart-object/lists"}