{"id":24764453,"url":"https://github.com/seamapi/url-search-params-serializer","last_synced_at":"2025-03-23T16:28:06.208Z","repository":{"id":216776128,"uuid":"741268397","full_name":"seamapi/url-search-params-serializer","owner":"seamapi","description":"Serializes JavaScript objects to The URLSearchParams.","archived":false,"fork":false,"pushed_at":"2025-03-10T06:22:32.000Z","size":607,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-19T09:42:58.425Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/seamapi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2024-01-10T03:27:06.000Z","updated_at":"2025-03-10T06:22:35.000Z","dependencies_parsed_at":"2024-01-12T20:03:13.546Z","dependency_job_id":null,"html_url":"https://github.com/seamapi/url-search-params-serializer","commit_stats":null,"previous_names":["seamapi/url-search-params-serializer"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seamapi%2Furl-search-params-serializer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seamapi%2Furl-search-params-serializer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seamapi%2Furl-search-params-serializer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seamapi%2Furl-search-params-serializer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seamapi","download_url":"https://codeload.github.com/seamapi/url-search-params-serializer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245130179,"owners_count":20565609,"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","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":[],"created_at":"2025-01-28T22:31:20.659Z","updated_at":"2025-03-23T16:28:06.179Z","avatar_url":"https://github.com/seamapi.png","language":"TypeScript","readme":"# URLSearchParams Serializer\n\n[![npm](https://img.shields.io/npm/v/@seamapi/url-search-params-serializer.svg)](https://www.npmjs.com/package/@seamapi/url-search-params-serializer)\n[![GitHub Actions](https://github.com/seamapi/url-search-params-serializer/actions/workflows/check.yml/badge.svg)](https://github.com/seamapi/url-search-params-serializer/actions/workflows/check.yml)\n\nSerializes JavaScript objects to URLSearchParams.\n\n## Description\n\nDefines the standard for how the Seam SDKs and other Seam API consumers\nshould serialize objects to [URLSearchParams] in HTTP GET requests.\nServes as a reference implementation for Seam SDKs in other languages.\n\nSee this test for the [serialization behavior](./test/serialization.test.ts).\n\n[URLSearchParams]: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams\n\n### Serialization strategy\n\nSerialization uses\n[`URLSearchParams.toString()`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/toString#return_value)\nwhich encodes most non-alphanumeric characters.\n\nSerialization is guaranteed to be well-defined within each type, i.e.,\nif the type of value for a given key in the query string is fixed and known by\nthe consumer parsing the string, it can be unambigously parsed back to the original primitive value.\n\n- The primitive type `string` is serialized using `.toString()`.\n- The primitive `number` and `bigint` types are serialized using `.toString()`.\n- The primitive `boolean` type is serialized using `.toString()`,\n  e.g., `{ foo: true, bar: false }` serializes to `foo=true\u0026bar=false`.\n- The primitive `null` and `undefined` values are removed,\n  e.g., `{ foo: null, bar: undefined, baz: 1 }` serializes to `baz=1`.\n- `Date` objects are detected and serialized using `Date.toISOString()`,\n  e.g., `{ foo: new Date(0) }` serializes to `foo=1970-01-01T00%3A00%3A00.000Z`.\n- `Temporal.Instant` objects are detected and serialized by first converting them to `Date`\n  and then serializing the `Date` as above.\n- Arrays are serialized using\n  [`URLSearchParams.append()`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/append):\n  - Array values are serialized as above.\n  - The array `{ foo: [1, 2] }` serializes to `foo=1\u0026foo=2`.\n  - The single element array `{ foo: [1] }` serializes to `foo=1`.\n  - The empty array `{ foo: [] }` serializes to `foo=`.\n  - Serialization of arrays containing `null` or `undefined` values\n    is not supported and will throw an `UnserializableParamError`.\n  - Serialization of the single element array containing the empty string\n    is not supported and will throw an `UnserializableParamError`.\n    Otherwise, the serialization of `{ foo: [''] }` would conflict with `{ foo: [] }`.\n    This serializer chooses to support the more common and more useful case of an empty array.\n- Serialization of objects and nested objects first serializes the keys\n  to dot-path format and then serializes the values as above, e.g.,\n  `{ foo: 'a', bar: { baz: 'b', fizz: [1, 2] } }` serializes to\n  `foo=a\u0026bar.baz=b\u0026bar.fizz=1\u0026bar.fizz=2`.\n- Serialization of nested arrays or objects nested inside arrays\n  is not supported and will throw an `UnserializableParamError`.\n- Serialization of functions or other objects is\n  is not supported and will throw an `UnserializableParamError`.\n\n## Installation\n\nAdd this as a dependency to your project using [npm] with\n\n```\n$ npm install @seamapi/url-search-params-serializer\n```\n\n[npm]: https://www.npmjs.com/\n\n## Usage\n\n### Serialize an object to a string\n\n```ts\nimport { serializeUrlSearchParams } from '@seamapi/url-search-params-serializer'\n\nserializeUrlSearchParams({\n  name: 'Dax',\n  age: 27,\n  isAdmin: true,\n  tags: ['cars', 'planes'],\n}) // =\u003e 'age=27\u0026isAdmin=true\u0026name=Dax\u0026tags=cars\u0026tags=planes'\n```\n\n### Update an existing URLSearchParams instance\n\n```ts\nimport { updateUrlSearchParams } from '@seamapi/url-search-params-serializer'\n\nconst searchParams = new URLSearchParams()\n\nsearchParams.set('foo', 'bar')\n\nupdateUrlSearchParams(searchParams, {\n  name: 'Dax',\n  age: 27,\n  isAdmin: true,\n  tags: ['cars', 'planes'],\n})\n\nsearchParams.toString() // =\u003e 'age=27\u0026foo=bar\u0026isAdmin=true\u0026name=Dax\u0026tags=cars\u0026tags=planes'\n```\n\n### Use directly with [Axios]\n\n```ts\nimport axios from 'axios'\nimport { serializeUrlSearchParams } from '@seamapi/url-search-params-serializer'\n\nconst client = axios.create({\n  paramsSerializer: serializeUrlSearchParams,\n  baseURL: 'https://example.com',\n})\n\nconst { data } = await client.get('/search', {\n  params: {\n    name: 'Dax',\n    age: 27,\n    isAdmin: true,\n    tags: ['cars', 'planes'],\n  },\n})\n```\n\n[Axios]: https://axios-http.com/\n\n## Motivation\n\nURL search parameters are strings, however the Seam API will parse parameters as complex types.\nThe Seam SDK must accept the complex types as input and serialize these\nto search parameters in a way supported by the Seam API.\n\nThere is no single standard for this serialization.\nThis module establishes the serialization standard adopted by the Seam API.\n\n### Why not use [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams)?\n\n- Passing a raw object to URLSearchParams has unpredictable serialization behavior.\n\n### Why not [qs](https://github.com/ljharb/qs)?\n\n- Not a zero-dependency module. Has quite a few dependency layers.\n- Impractical as a reference implementation.\n  qs enables complex, non-standard parsing and serialization,\n  which makes ensuing SDK parity much harder.\n  Similarly, this puts an unreasonable burden on user's of the HTTP API or those implementing their own client.\n- The Seam API must ensure it handles a well defined set of non-string query parameters consistency.\n  Using qs would allow the SDK to send unsupported or incorrectly serialized parameter types to the API\n  resulting in unexpected behavior.\n\n### Why not use the default [Axios](https://axios-http.com/) serializer?\n\n- Using the default [Axios] serializer was the original approach,\n  however it had similar issues to using URLSearchParams and qs as noted above.\n\n## Development and Testing\n\n### Quickstart\n\n```\n$ git clone https://github.com/seamapi/url-search-params-serializer.git\n$ cd url-search-params-serializer\n$ nvm install\n$ npm install\n$ npm run test:watch\n```\n\nPrimary development tasks are defined under `scripts` in `package.json`\nand available via `npm run`.\nView them with\n\n```\n$ npm run\n```\n\n### Source code\n\nThe [source code] is hosted on GitHub.\nClone the project with\n\n```\n$ git clone git@github.com:seamapi/url-search-params-serializer.git\n```\n\n[source code]: https://github.com/seamapi/url-search-params-serializer\n\n### Requirements\n\nYou will need [Node.js] with [npm] and a [Node.js debugging] client.\n\nBe sure that all commands run under the correct Node version, e.g.,\nif using [nvm], install the correct version with\n\n```\n$ nvm install\n```\n\nSet the active version for each shell session with\n\n```\n$ nvm use\n```\n\nInstall the development dependencies with\n\n```\n$ npm install\n```\n\n[Node.js]: https://nodejs.org/\n[Node.js debugging]: https://nodejs.org/en/docs/guides/debugging-getting-started/\n[npm]: https://www.npmjs.com/\n[nvm]: https://github.com/creationix/nvm\n\n### Publishing\n\n#### Automatic\n\nNew versions are released automatically with [semantic-release]\nas long as commits follow the [Angular Commit Message Conventions].\n\n[Angular Commit Message Conventions]: https://semantic-release.gitbook.io/semantic-release/#commit-message-format\n[semantic-release]: https://semantic-release.gitbook.io/\n\n#### Manual\n\nPublish a new version by triggering a [version workflow_dispatch on GitHub Actions].\nThe `version` input will be passed as the first argument to [npm-version].\n\nThis may be done on the web or using the [GitHub CLI] with\n\n```\n$ gh workflow run version.yml --raw-field version=\u003cversion\u003e\n```\n\n[GitHub CLI]: https://cli.github.com/\n[npm-version]: https://docs.npmjs.com/cli/version\n[version workflow_dispatch on GitHub Actions]: https://github.com/seamapi/url-search-params-serializer/actions?query=workflow%3Aversion\n\n## GitHub Actions\n\n_GitHub Actions should already be configured: this section is for reference only._\n\nThe following repository secrets must be set on [GitHub Actions]:\n\n- `NPM_TOKEN`: npm token for installing and publishing packages.\n- `GH_TOKEN`: A personal access token for the bot user with\n  `packages:write` and `contents:write` permission.\n- `GIT_USER_NAME`: The GitHub bot user's real name.\n- `GIT_USER_EMAIL`: The GitHub bot user's email.\n- `GPG_PRIVATE_KEY`: The GitHub bot user's [GPG private key].\n- `GPG_PASSPHRASE`: The GitHub bot user's GPG passphrase.\n\n[GitHub Actions]: https://github.com/features/actions\n[GPG private key]: https://github.com/marketplace/actions/import-gpg#prerequisites\n\n## Contributing\n\n\u003e If using squash merge, edit and ensure the commit message follows the [Angular Commit Message Conventions] specification.\n\u003e Otherwise, each individual commit must follow the [Angular Commit Message Conventions] specification.\n\n1. Create your feature branch (`git checkout -b my-new-feature`).\n2. Make changes.\n3. Commit your changes (`git commit -am 'Add some feature'`).\n4. Push to the branch (`git push origin my-new-feature`).\n5. Create a new draft pull request.\n6. Ensure all checks pass.\n7. Mark your pull request ready for review.\n8. Wait for the required approval from the code owners.\n9. Merge when ready.\n\n[Angular Commit Message Conventions]: https://semantic-release.gitbook.io/semantic-release/#commit-message-format\n\n## License\n\nThis npm package is licensed under the MIT license.\n\n## Warranty\n\nThis software is provided by the copyright holders and contributors \"as is\" and\nany express or implied warranties, including, but not limited to, the implied\nwarranties of merchantability and fitness for a particular purpose are\ndisclaimed. In no event shall the copyright holder or contributors be liable for\nany direct, indirect, incidental, special, exemplary, or consequential damages\n(including, but not limited to, procurement of substitute goods or services;\nloss of use, data, or profits; or business interruption) however caused and on\nany theory of liability, whether in contract, strict liability, or tort\n(including negligence or otherwise) arising in any way out of the use of this\nsoftware, even if advised of the possibility of such damage.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseamapi%2Furl-search-params-serializer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseamapi%2Furl-search-params-serializer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseamapi%2Furl-search-params-serializer/lists"}