diff --git a/.changeset/kind-rings-attend.md b/.changeset/kind-rings-attend.md new file mode 100644 index 0000000..16c4abc --- /dev/null +++ b/.changeset/kind-rings-attend.md @@ -0,0 +1,8 @@ +--- +"@rescript-relay-router-example/client-rendering": minor +"@rescript-relay-router-example/express": minor +"rescript-relay-router": minor +"@rescript-relay-router/utils": minor +--- + +remove query param from URL when its value is default diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ca11f65..910bdd9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,11 +38,6 @@ jobs: - name: Build all projects run: | yarn build - # Since we don't want to have generated code formatted in the router we regenerate - # the router code after formatting. - - name: Sync router code generation - run: | - yarn workspaces foreach --topological-dev run router:generate - name: git status id: git_status shell: bash diff --git a/examples/client-rendering/package.json b/examples/client-rendering/package.json index 9bf1619..2e3ed31 100644 --- a/examples/client-rendering/package.json +++ b/examples/client-rendering/package.json @@ -8,7 +8,7 @@ "type": "module", "packageManager": "yarn@3.2.1", "scripts": { - "build": "run-s 'build:*'", + "build": "yarn router:generate && run-s 'build:*'", "build:relay": "rescript-relay-compiler", "build:rescript": "rescript build -with-deps", "build:vite": "vite build --outDir dist/client", diff --git a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecodedExtra_route.res b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecodedExtra_route.res index 03f6706..0e32601 100644 --- a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecodedExtra_route.res +++ b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecodedExtra_route.res @@ -79,7 +79,7 @@ let applyQueryParams = ( queryParams->QueryParams.setParamArrayOpt(~key="statuses", ~value=newParams.statuses->Option.map(statuses => statuses->Array.map(statuses => statuses->TodoStatus.serialize))) - queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=newParams.statusWithDefault->TodoStatus.serialize) + queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=newParams.statusWithDefault == TodoStatus.defaultValue ? None : newParams.statusWithDefault->TodoStatus.serialize->Some) queryParams->QueryParams.setParamOpt(~key="byValue", ~value=newParams.byValue->Option.map(byValue => byValue)) } @@ -122,7 +122,7 @@ let makeLink = (~byStatusDecoded: TodoStatusPathParam.t, ~statuses: option () - | Some(statusWithDefault) => queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=statusWithDefault->TodoStatus.serialize) + | Some(statusWithDefault) => queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=statusWithDefault == TodoStatus.defaultValue ? None : statusWithDefault->TodoStatus.serialize->Some) } switch byValue { diff --git a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecoded__Child_route.res b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecoded__Child_route.res index d504709..ee6259e 100644 --- a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecoded__Child_route.res +++ b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecoded__Child_route.res @@ -79,7 +79,7 @@ let applyQueryParams = ( queryParams->QueryParams.setParamArrayOpt(~key="statuses", ~value=newParams.statuses->Option.map(statuses => statuses->Array.map(statuses => statuses->TodoStatus.serialize))) - queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=newParams.statusWithDefault->TodoStatus.serialize) + queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=newParams.statusWithDefault == TodoStatus.defaultValue ? None : newParams.statusWithDefault->TodoStatus.serialize->Some) queryParams->QueryParams.setParamOpt(~key="byValue", ~value=newParams.byValue->Option.map(byValue => byValue)) } @@ -122,7 +122,7 @@ let makeLink = (~byStatusDecoded: TodoStatusPathParam.t, ~statuses: option () - | Some(statusWithDefault) => queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=statusWithDefault->TodoStatus.serialize) + | Some(statusWithDefault) => queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=statusWithDefault == TodoStatus.defaultValue ? None : statusWithDefault->TodoStatus.serialize->Some) } switch byValue { diff --git a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecoded_route.res b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecoded_route.res index 4b883f8..8eb1d00 100644 --- a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecoded_route.res +++ b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatusDecoded_route.res @@ -87,7 +87,7 @@ let applyQueryParams = ( queryParams->QueryParams.setParamArrayOpt(~key="statuses", ~value=newParams.statuses->Option.map(statuses => statuses->Array.map(statuses => statuses->TodoStatus.serialize))) - queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=newParams.statusWithDefault->TodoStatus.serialize) + queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=newParams.statusWithDefault == TodoStatus.defaultValue ? None : newParams.statusWithDefault->TodoStatus.serialize->Some) queryParams->QueryParams.setParamOpt(~key="byValue", ~value=newParams.byValue->Option.map(byValue => byValue)) } @@ -130,7 +130,7 @@ let makeLink = (~byStatusDecoded: TodoStatusPathParam.t, ~statuses: option () - | Some(statusWithDefault) => queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=statusWithDefault->TodoStatus.serialize) + | Some(statusWithDefault) => queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=statusWithDefault == TodoStatus.defaultValue ? None : statusWithDefault->TodoStatus.serialize->Some) } switch byValue { diff --git a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatus_route.res b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatus_route.res index e303671..01113dc 100644 --- a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatus_route.res +++ b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__ByStatus_route.res @@ -79,7 +79,7 @@ let applyQueryParams = ( queryParams->QueryParams.setParamArrayOpt(~key="statuses", ~value=newParams.statuses->Option.map(statuses => statuses->Array.map(statuses => statuses->TodoStatus.serialize))) - queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=newParams.statusWithDefault->TodoStatus.serialize) + queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=newParams.statusWithDefault == TodoStatus.defaultValue ? None : newParams.statusWithDefault->TodoStatus.serialize->Some) queryParams->QueryParams.setParamOpt(~key="byValue", ~value=newParams.byValue->Option.map(byValue => byValue)) } @@ -122,7 +122,7 @@ let makeLink = (~byStatus: [#"completed" | #"not-completed"], ~statuses: option< switch statusWithDefault { | None => () - | Some(statusWithDefault) => queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=statusWithDefault->TodoStatus.serialize) + | Some(statusWithDefault) => queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=statusWithDefault == TodoStatus.defaultValue ? None : statusWithDefault->TodoStatus.serialize->Some) } switch byValue { diff --git a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__Single_route.res b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__Single_route.res index a3e2c1d..43f6b55 100644 --- a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__Single_route.res +++ b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos__Single_route.res @@ -91,7 +91,7 @@ let applyQueryParams = ( queryParams->QueryParams.setParamArrayOpt(~key="statuses", ~value=newParams.statuses->Option.map(statuses => statuses->Array.map(statuses => statuses->TodoStatus.serialize))) - queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=newParams.statusWithDefault->TodoStatus.serialize) + queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=newParams.statusWithDefault == TodoStatus.defaultValue ? None : newParams.statusWithDefault->TodoStatus.serialize->Some) queryParams->QueryParams.setParamOpt(~key="byValue", ~value=newParams.byValue->Option.map(byValue => byValue)) queryParams->QueryParams.setParamOpt(~key="showMore", ~value=newParams.showMore->Option.map(showMore => switch showMore { | true => "true" | false => "false" })) } @@ -135,7 +135,7 @@ let makeLink = (~todoId: string, ~statuses: option>=?, ~stat switch statusWithDefault { | None => () - | Some(statusWithDefault) => queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=statusWithDefault->TodoStatus.serialize) + | Some(statusWithDefault) => queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=statusWithDefault == TodoStatus.defaultValue ? None : statusWithDefault->TodoStatus.serialize->Some) } switch byValue { diff --git a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos_route.res b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos_route.res index bbc1fd6..c318e9a 100644 --- a/examples/client-rendering/src/routes/__generated__/Route__Root__Todos_route.res +++ b/examples/client-rendering/src/routes/__generated__/Route__Root__Todos_route.res @@ -81,7 +81,7 @@ let applyQueryParams = ( queryParams->QueryParams.setParamArrayOpt(~key="statuses", ~value=newParams.statuses->Option.map(statuses => statuses->Array.map(statuses => statuses->TodoStatus.serialize))) - queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=newParams.statusWithDefault->TodoStatus.serialize) + queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=newParams.statusWithDefault == TodoStatus.defaultValue ? None : newParams.statusWithDefault->TodoStatus.serialize->Some) queryParams->QueryParams.setParamOpt(~key="byValue", ~value=newParams.byValue->Option.map(byValue => byValue)) } @@ -124,7 +124,7 @@ let makeLink = (~statuses: option>=?, ~statusWithDefault: op switch statusWithDefault { | None => () - | Some(statusWithDefault) => queryParams->QueryParams.setParam(~key="statusWithDefault", ~value=statusWithDefault->TodoStatus.serialize) + | Some(statusWithDefault) => queryParams->QueryParams.setParamOpt(~key="statusWithDefault", ~value=statusWithDefault == TodoStatus.defaultValue ? None : statusWithDefault->TodoStatus.serialize->Some) } switch byValue { diff --git a/examples/client-rendering/test/UrlEncodingDecoding.test.res b/examples/client-rendering/test/UrlEncodingDecoding.test.res index 85167a1..7070daa 100644 --- a/examples/client-rendering/test/UrlEncodingDecoding.test.res +++ b/examples/client-rendering/test/UrlEncodingDecoding.test.res @@ -17,6 +17,11 @@ describe("makeLink", () => { let link = Routes.Root.Todos.Route.makeLink(~byValue="/incorrect value, for url") expect(link)->Expect.toBe("/todos?byValue=%2Fincorrect%20value%2C%20for%20url") }) + + test("should omit query param when value is default value", _t => { + let link = Routes.Root.Todos.Route.makeLink(~statusWithDefault=NotCompleted) + expect(link)->Expect.toBe("/todos") + }) }) describe("parsing", () => { diff --git a/examples/express/package.json b/examples/express/package.json index f859b3d..ca4d673 100644 --- a/examples/express/package.json +++ b/examples/express/package.json @@ -8,7 +8,7 @@ "type": "module", "packageManager": "yarn@3.2.1", "scripts": { - "build": "run-s 'build:*'", + "build": "yarn router:generate && run-s 'build:*'", "build:relay": "rescript-relay-compiler", "build:rescript": "rescript build -with-deps", "build:vite": "run-s 'build:vite:*'", diff --git a/packages/rescript-relay-router/cli/RescriptRelayRouterCli__Codegen.res b/packages/rescript-relay-router/cli/RescriptRelayRouterCli__Codegen.res index a4fe4f0..7e479f7 100644 --- a/packages/rescript-relay-router/cli/RescriptRelayRouterCli__Codegen.res +++ b/packages/rescript-relay-router/cli/RescriptRelayRouterCli__Codegen.res @@ -100,6 +100,7 @@ let routePattern = "${route.path->RoutePath.toPattern}" queryParamSerializers->Array.forEach(((key, serializer, paramType)) => { let serializerStr = `queryParams->QueryParams.${switch paramType { | Array(_) => "setParamArray" + | CustomModule({required: true}) => "setParamOpt" | _ => "setParam" }}(~key="${key->SafeParam.getOriginalKey}", ~value=${serializer})` @@ -231,7 +232,7 @@ let applyQueryParams = ( ~variableName=key, )})))` | CustomModule({required: true}) => - `\n queryParams->QueryParams.setParam(~key="${key}", ~value=${queryParam->Utils.QueryParams.toSerializer( + `\n queryParams->QueryParams.setParamOpt(~key="${key}", ~value=${queryParam->Utils.QueryParams.toSerializer( ~variableName=`newParams.${key}`, )})` | queryParam => diff --git a/packages/rescript-relay-router/cli/RescriptRelayRouterCli__Utils.res b/packages/rescript-relay-router/cli/RescriptRelayRouterCli__Utils.res index 5025327..192fe7a 100644 --- a/packages/rescript-relay-router/cli/RescriptRelayRouterCli__Utils.res +++ b/packages/rescript-relay-router/cli/RescriptRelayRouterCli__Utils.res @@ -85,6 +85,8 @@ module QueryParams = { | Boolean => `switch ${variableName} { | true => "true" | false => "false" }` | Int => `Int.toString(${variableName})` | Float => `Float.toString(${variableName})` + | CustomModule({moduleName, required: true}) => + `${variableName} == ${moduleName}.defaultValue ? None : ${variableName}->${moduleName}.serialize->Some` | CustomModule({moduleName}) => `${variableName}->${moduleName}.serialize` | Array(inner) => switch inner {