Skip to content

Commit 04f54c2

Browse files
committed
feat(history-sync): add encode interface
1 parent 3c2553a commit 04f54c2

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@stackflow/plugin-history-sync": minor
3+
---
4+
5+
Add `encode` interface

extensions/plugin-history-sync/src/RouteLike.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ export type Route<K> = {
44
path: string;
55
decode?: (
66
params: Record<string, string>,
7-
) => K extends ActivityComponentType<infer U> ? U : {};
7+
) => K extends ActivityComponentType<infer U> ? U : Record<string, unknown>;
8+
encode?: (
9+
params: K extends ActivityComponentType<infer U>
10+
? U
11+
: Record<string, unknown>,
12+
) => Record<string, string>;
813
};
914

1015
export type RouteLike<T> = string | string[] | Route<T> | Route<T>[];

extensions/plugin-history-sync/src/makeTemplate.spec.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,37 @@ test("makeTemplate - parse with given decode function", () => {
7676
articleId: 1234,
7777
});
7878
});
79+
80+
test("makeTemplate - fill with given encode function", () => {
81+
const template = makeTemplate({
82+
path: "/articles/:articleId",
83+
encode: ({ id }) => ({
84+
articleId: String(id),
85+
}),
86+
});
87+
88+
expect(template.fill({ id: 1234 as unknown as string })).toEqual(
89+
"/articles/1234/",
90+
);
91+
});
92+
93+
test("makeTemplate - roundtrip with given encode and decode function", () => {
94+
const template = makeTemplate({
95+
path: "/articles/:articleId",
96+
encode: ({ id }) => ({
97+
articleId: String(id),
98+
}),
99+
decode: ({ articleId }) => ({
100+
id: Number(articleId),
101+
}),
102+
});
103+
104+
expect(template.fill(template.parse("/articles/1234/") ?? {})).toStrictEqual(
105+
"/articles/1234/",
106+
);
107+
expect(
108+
template.parse(template.fill({ id: 1234 as unknown as string })),
109+
).toStrictEqual({
110+
id: 1234,
111+
});
112+
});

extensions/plugin-history-sync/src/makeTemplate.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export interface UrlPatternOptions {
4646
}
4747

4848
export function makeTemplate<T>(
49-
{ path, decode }: Route<T>,
49+
{ path, decode, encode }: Route<T>,
5050
urlPatternOptions?: UrlPatternOptions,
5151
) {
5252
const pattern = new UrlPattern(`${path}(/)`, urlPatternOptions);
@@ -59,10 +59,11 @@ export function makeTemplate<T>(
5959

6060
return {
6161
fill(params: { [key: string]: string | undefined }) {
62-
const pathname = pattern.stringify(params);
62+
const encodedParams = encode ? encode(params as any) : params;
63+
const pathname = pattern.stringify(encodedParams);
6364
const pathParams = pattern.match(pathname);
6465

65-
const searchParamsMap = { ...params };
66+
const searchParamsMap = { ...encodedParams };
6667

6768
Object.keys(pathParams).forEach((key) => {
6869
delete searchParamsMap[key];

0 commit comments

Comments
 (0)