diff --git a/src/application/environment/environmentReplay.ts b/src/application/environment/environmentReplay.ts index db83a8e524..730202da55 100644 --- a/src/application/environment/environmentReplay.ts +++ b/src/application/environment/environmentReplay.ts @@ -1,3 +1,4 @@ +import { decodedSegment } from "../../domain/analysisView/environmentStateRules.js"; import type { AnalysisError } from "../../domain/analysisErrorBase.js"; import { AnalysisInputError } from "../../domain/analysisErrorCore.js"; import type { JsonValue } from "../../domain/jsonValue.js"; @@ -47,18 +48,9 @@ interface MatchScore { readonly exact: boolean; } -/** A path segment percent-decoded, or as written when it is not valid percent-encoding. */ -export const decodedPathSegment = (segment: string): string => { - try { - return decodeURIComponent(segment); - } catch { - return segment; - } -}; - /** Replay's path rule: a supplied value matches a recorded segment equal to it verbatim or after percent-decoding. */ export const pathValueMatches = (segment: string, value: string): boolean => - segment === value || decodedPathSegment(segment) === value; + segment === value || decodedSegment(segment) === value; /** Count how many supplied path and query values the recorded request line satisfies. */ const scoreExchange = ( diff --git a/src/application/environment/environmentStateAnswer.ts b/src/application/environment/environmentStateAnswer.ts index 184e50fc15..cfd6739661 100644 --- a/src/application/environment/environmentStateAnswer.ts +++ b/src/application/environment/environmentStateAnswer.ts @@ -1,6 +1,7 @@ import { stateBodyJson } from "../../domain/analysisView/EnvironmentStateAccumulator.js"; import { collectionPathOf, + decodedSegment, listItems, missingRequiredFields, renderStateEntity, @@ -28,7 +29,6 @@ import { import type { JsonValue } from "../../domain/jsonValue.js"; import { err, ok, type Result } from "../../domain/result.js"; import { - decodedPathSegment, pathValueMatches, replayAnswer, replayEnvironmentTool, @@ -243,7 +243,7 @@ export const namedEntity = ( type: string, call: ItemCall, ): StateEntity | undefined => { - const ids = [...new Set([decodedPathSegment(call.id), call.id])]; + const ids = [...new Set([decodedSegment(call.id), call.id])]; const candidates = store .collectionsOf(type) .flatMap((collection) => { diff --git a/src/domain/analysisView/environmentStateWriteRules.ts b/src/domain/analysisView/environmentStateWriteRules.ts index bf315fee74..58a598a669 100644 --- a/src/domain/analysisView/environmentStateWriteRules.ts +++ b/src/domain/analysisView/environmentStateWriteRules.ts @@ -1,5 +1,6 @@ import type { JsonValue } from "../jsonValue.js"; import { + decodedSegment, isParam, normalizedPath, segmentsOf, @@ -187,13 +188,7 @@ export const pathValuesOf = ( if (segment !== value) return undefined; continue; } - let decoded = value; - try { - decoded = decodeURIComponent(value); - } catch { - decoded = value; - } - values.set(segment.slice(1, -1), decoded); + values.set(segment.slice(1, -1), decodedSegment(value)); } return values; };