diff --git a/apps/builder/app/builder/shared/url-pattern.test.ts b/apps/builder/app/builder/shared/url-pattern.test.ts index a12f8045b58c..40473a0bad7f 100644 --- a/apps/builder/app/builder/shared/url-pattern.test.ts +++ b/apps/builder/app/builder/shared/url-pattern.test.ts @@ -2,10 +2,25 @@ import { expect, test } from "vitest"; import { compilePathnamePattern, isPathnamePattern, + matchPathnamePattern, tokenizePathnamePattern, validatePathnamePattern, } from "./url-pattern"; +test("decode matched params", () => { + expect(matchPathnamePattern("/blog/:slug", "/blog/привет")).toEqual({ + slug: "привет", + }); + expect( + matchPathnamePattern( + "/blog/:slug", + "/blog/%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82" + ) + ).toEqual({ + slug: "привет", + }); +}); + test("check pathname is pattern", () => { expect(isPathnamePattern("/:name")).toEqual(true); expect(isPathnamePattern("/:slug*")).toEqual(true); diff --git a/apps/builder/app/builder/shared/url-pattern.ts b/apps/builder/app/builder/shared/url-pattern.ts index 996e0c6c3394..6371fa87a5ce 100644 --- a/apps/builder/app/builder/shared/url-pattern.ts +++ b/apps/builder/app/builder/shared/url-pattern.ts @@ -1,13 +1,31 @@ import { matchPathnameParams } from "@webstudio-is/sdk"; import { URLPattern } from "urlpattern-polyfill"; + export { isPathnamePattern } from "@webstudio-is/sdk"; const baseUrl = "http://url"; +const tryDecode = (encoded: string) => { + try { + return decodeURIComponent(encoded); + } catch { + return encoded; + } +}; + export const matchPathnamePattern = (pattern: string, pathname: string) => { try { - return new URLPattern({ pathname: pattern }).exec({ pathname })?.pathname - .groups; + const groups = new URLPattern({ pathname: pattern }).exec({ pathname }) + ?.pathname.groups; + if (groups) { + const decodedGroups: Record = {}; + for (const [name, value] of Object.entries(groups)) { + if (value) { + decodedGroups[name] = tryDecode(value); + } + } + return decodedGroups; + } } catch { // empty block } diff --git a/apps/builder/package.json b/apps/builder/package.json index 0b7198a9fdb4..c6db3c681fb2 100644 --- a/apps/builder/package.json +++ b/apps/builder/package.json @@ -119,7 +119,7 @@ "strip-indent": "^4.0.0", "tiny-invariant": "^1.3.3", "title-case": "^4.3.2", - "urlpattern-polyfill": "^10.0.0", + "urlpattern-polyfill": "^10.1.0", "use-debounce": "^10.0.4", "valid-filename": "^4.0.0", "warn-once": "^0.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7ed11a7f6e5..414d74d95322 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -419,8 +419,8 @@ importers: specifier: ^4.3.2 version: 4.3.2 urlpattern-polyfill: - specifier: ^10.0.0 - version: 10.0.0 + specifier: ^10.1.0 + version: 10.1.0 use-debounce: specifier: ^10.0.4 version: 10.0.4(react@18.3.0-canary-14898b6a9-20240318) @@ -9042,8 +9042,8 @@ packages: url-parse@1.5.10: resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} - urlpattern-polyfill@10.0.0: - resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} + urlpattern-polyfill@10.1.0: + resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} urlpattern-polyfill@4.0.3: resolution: {integrity: sha512-DOE84vZT2fEcl9gqCUTcnAw5ZY5Id55ikUcziSUntuEFL3pRvavg5kwDmTEUJkeCHInTlV/HexFomgYnzO5kdQ==} @@ -13006,7 +13006,7 @@ snapshots: '@whatwg-node/fetch@0.9.23': dependencies: '@whatwg-node/node-fetch': 0.6.0 - urlpattern-polyfill: 10.0.0 + urlpattern-polyfill: 10.1.0 '@whatwg-node/node-fetch@0.6.0': dependencies: @@ -16958,7 +16958,7 @@ snapshots: requires-port: 1.0.0 optional: true - urlpattern-polyfill@10.0.0: {} + urlpattern-polyfill@10.1.0: {} urlpattern-polyfill@4.0.3: {}