@tanstack/react-router 1.92.1 → 1.92.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/transformer.cjs +88 -25
- package/dist/cjs/transformer.cjs.map +1 -1
- package/dist/cjs/transformer.d.cts +2 -0
- package/dist/esm/transformer.d.ts +2 -0
- package/dist/esm/transformer.js +88 -25
- package/dist/esm/transformer.js.map +1 -1
- package/package.json +1 -1
- package/src/transformer.ts +105 -26
package/dist/cjs/transformer.cjs
CHANGED
|
@@ -2,38 +2,101 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const utils = require("./utils.cjs");
|
|
4
4
|
const defaultTransformer = {
|
|
5
|
-
stringify: (value) => JSON.stringify(value, function replacer(key,
|
|
6
|
-
const
|
|
7
|
-
const transformer = transformers.find((t) => t.stringifyCondition(
|
|
5
|
+
stringify: (value) => JSON.stringify(value, function replacer(key, val) {
|
|
6
|
+
const ogVal = this[key];
|
|
7
|
+
const transformer = transformers.find((t) => t.stringifyCondition(ogVal));
|
|
8
8
|
if (transformer) {
|
|
9
|
-
return transformer.stringify(
|
|
9
|
+
return transformer.stringify(ogVal);
|
|
10
10
|
}
|
|
11
|
-
return
|
|
11
|
+
return val;
|
|
12
12
|
}),
|
|
13
|
-
parse: (value) => JSON.parse(value, function parser(key,
|
|
14
|
-
const
|
|
15
|
-
|
|
13
|
+
parse: (value) => JSON.parse(value, function parser(key, val) {
|
|
14
|
+
const ogVal = this[key];
|
|
15
|
+
if (utils.isPlainObject(ogVal)) {
|
|
16
|
+
const transformer = transformers.find((t) => t.parseCondition(ogVal));
|
|
17
|
+
if (transformer) {
|
|
18
|
+
return transformer.parse(ogVal);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return val;
|
|
22
|
+
}),
|
|
23
|
+
encode: (value) => {
|
|
24
|
+
if (Array.isArray(value)) {
|
|
25
|
+
return value.map((v) => defaultTransformer.encode(v));
|
|
26
|
+
}
|
|
27
|
+
if (utils.isPlainObject(value)) {
|
|
28
|
+
return Object.fromEntries(
|
|
29
|
+
Object.entries(value).map(([key, v]) => [
|
|
30
|
+
key,
|
|
31
|
+
defaultTransformer.encode(v)
|
|
32
|
+
])
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
const transformer = transformers.find((t) => t.stringifyCondition(value));
|
|
16
36
|
if (transformer) {
|
|
17
|
-
return transformer.
|
|
37
|
+
return transformer.stringify(value);
|
|
18
38
|
}
|
|
19
|
-
return
|
|
20
|
-
})
|
|
21
|
-
};
|
|
22
|
-
const transformers = [
|
|
23
|
-
{
|
|
24
|
-
// Dates
|
|
25
|
-
stringifyCondition: (value) => value instanceof Date,
|
|
26
|
-
stringify: (value) => ({ $date: value.toISOString() }),
|
|
27
|
-
parseCondition: (value) => utils.isPlainObject(value) && value.$date,
|
|
28
|
-
parse: (value) => new Date(value.$date)
|
|
39
|
+
return value;
|
|
29
40
|
},
|
|
30
|
-
{
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
decode: (value) => {
|
|
42
|
+
if (utils.isPlainObject(value)) {
|
|
43
|
+
const transformer = transformers.find((t) => t.parseCondition(value));
|
|
44
|
+
if (transformer) {
|
|
45
|
+
return transformer.parse(value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
return value.map((v) => defaultTransformer.decode(v));
|
|
50
|
+
}
|
|
51
|
+
if (utils.isPlainObject(value)) {
|
|
52
|
+
return Object.fromEntries(
|
|
53
|
+
Object.entries(value).map(([key, v]) => [
|
|
54
|
+
key,
|
|
55
|
+
defaultTransformer.decode(v)
|
|
56
|
+
])
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
36
60
|
}
|
|
61
|
+
};
|
|
62
|
+
const createTransformer = (key, check, toValue = (v) => v, fromValue = (v) => v) => ({
|
|
63
|
+
key,
|
|
64
|
+
stringifyCondition: check,
|
|
65
|
+
stringify: (value) => ({ [`$${key}`]: toValue(value) }),
|
|
66
|
+
parseCondition: (value) => Object.hasOwn(value, `$${key}`),
|
|
67
|
+
parse: (value) => fromValue(value[`$${key}`])
|
|
68
|
+
});
|
|
69
|
+
const transformers = [
|
|
70
|
+
createTransformer(
|
|
71
|
+
// Key
|
|
72
|
+
"undefined",
|
|
73
|
+
// Check
|
|
74
|
+
(v) => v === void 0,
|
|
75
|
+
// To
|
|
76
|
+
() => 0,
|
|
77
|
+
// From
|
|
78
|
+
() => void 0
|
|
79
|
+
),
|
|
80
|
+
createTransformer(
|
|
81
|
+
// Key
|
|
82
|
+
"date",
|
|
83
|
+
// Check
|
|
84
|
+
(v) => v instanceof Date,
|
|
85
|
+
// To
|
|
86
|
+
(v) => v.toISOString(),
|
|
87
|
+
// From
|
|
88
|
+
(v) => new Date(v)
|
|
89
|
+
),
|
|
90
|
+
createTransformer(
|
|
91
|
+
// Key
|
|
92
|
+
"error",
|
|
93
|
+
// Check
|
|
94
|
+
(v) => v instanceof Error,
|
|
95
|
+
// To
|
|
96
|
+
(v) => ({ ...v, message: v.message, stack: v.stack, cause: v.cause }),
|
|
97
|
+
// From
|
|
98
|
+
(v) => Object.assign(new Error(v.message), v)
|
|
99
|
+
)
|
|
37
100
|
];
|
|
38
101
|
exports.defaultTransformer = defaultTransformer;
|
|
39
102
|
//# sourceMappingURL=transformer.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformer.cjs","sources":["../../src/transformer.ts"],"sourcesContent":["import { isPlainObject } from './utils'\n\nexport interface RouterTransformer {\n stringify: (obj: unknown) => string\n parse: (str: string) => unknown\n}\n\nexport const defaultTransformer: RouterTransformer = {\n stringify: (value: any) =>\n JSON.stringify(value, function replacer(key,
|
|
1
|
+
{"version":3,"file":"transformer.cjs","sources":["../../src/transformer.ts"],"sourcesContent":["import { isPlainObject } from './utils'\n\nexport interface RouterTransformer {\n stringify: (obj: unknown) => string\n parse: (str: string) => unknown\n encode: <T>(value: T) => T\n decode: <T>(value: T) => T\n}\n\nexport const defaultTransformer: RouterTransformer = {\n stringify: (value: any) =>\n JSON.stringify(value, function replacer(key, val) {\n const ogVal = this[key]\n const transformer = transformers.find((t) => t.stringifyCondition(ogVal))\n\n if (transformer) {\n return transformer.stringify(ogVal)\n }\n\n return val\n }),\n parse: (value: string) =>\n JSON.parse(value, function parser(key, val) {\n const ogVal = this[key]\n if (isPlainObject(ogVal)) {\n const transformer = transformers.find((t) => t.parseCondition(ogVal))\n\n if (transformer) {\n return transformer.parse(ogVal)\n }\n }\n\n return val\n }),\n encode: (value: any) => {\n // When encodign, dive first\n if (Array.isArray(value)) {\n return value.map((v) => defaultTransformer.encode(v))\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [\n key,\n defaultTransformer.encode(v),\n ]),\n )\n }\n\n const transformer = transformers.find((t) => t.stringifyCondition(value))\n if (transformer) {\n return transformer.stringify(value)\n }\n\n return value\n },\n decode: (value: any) => {\n // Attempt transform first\n if (isPlainObject(value)) {\n const transformer = transformers.find((t) => t.parseCondition(value))\n if (transformer) {\n return transformer.parse(value)\n }\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => defaultTransformer.decode(v))\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [\n key,\n defaultTransformer.decode(v),\n ]),\n )\n }\n\n return value\n },\n}\n\nconst createTransformer = <T extends string>(\n key: T,\n check: (value: any) => boolean,\n toValue: (value: any) => any = (v) => v,\n fromValue: (value: any) => any = (v) => v,\n) => ({\n key,\n stringifyCondition: check,\n stringify: (value: any) => ({ [`$${key}`]: toValue(value) }),\n parseCondition: (value: any) => Object.hasOwn(value, `$${key}`),\n parse: (value: any) => fromValue(value[`$${key}`]),\n})\n\n// Keep these ordered by predicted frequency\nconst transformers = [\n createTransformer(\n // Key\n 'undefined',\n // Check\n (v) => v === undefined,\n // To\n () => 0,\n // From\n () => undefined,\n ),\n createTransformer(\n // Key\n 'date',\n // Check\n (v) => v instanceof Date,\n // To\n (v) => v.toISOString(),\n // From\n (v) => new Date(v),\n ),\n createTransformer(\n // Key\n 'error',\n // Check\n (v) => v instanceof Error,\n // To\n (v) => ({ ...v, message: v.message, stack: v.stack, cause: v.cause }),\n // From\n (v) => Object.assign(new Error(v.message), v),\n ),\n] as const\n\nexport type TransformerStringify<T, TSerializable> = T extends TSerializable\n ? T\n : T extends (...args: Array<any>) => any\n ? 'Function is not serializable'\n : { [K in keyof T]: TransformerStringify<T[K], TSerializable> }\n\nexport type TransformerParse<T, TSerializable> = T extends TSerializable\n ? T\n : T extends React.JSX.Element\n ? ReadableStream\n : { [K in keyof T]: TransformerParse<T[K], TSerializable> }\n\nexport type DefaultTransformerStringify<T> = TransformerStringify<\n T,\n Date | undefined\n>\n\nexport type DefaultTransformerParse<T> = TransformerParse<T, Date | undefined>\n"],"names":["isPlainObject"],"mappings":";;;AASO,MAAM,qBAAwC;AAAA,EACnD,WAAW,CAAC,UACV,KAAK,UAAU,OAAO,SAAS,SAAS,KAAK,KAAK;AAC1C,UAAA,QAAQ,KAAK,GAAG;AAChB,UAAA,cAAc,aAAa,KAAK,CAAC,MAAM,EAAE,mBAAmB,KAAK,CAAC;AAExE,QAAI,aAAa;AACR,aAAA,YAAY,UAAU,KAAK;AAAA,IAAA;AAG7B,WAAA;AAAA,EAAA,CACR;AAAA,EACH,OAAO,CAAC,UACN,KAAK,MAAM,OAAO,SAAS,OAAO,KAAK,KAAK;AACpC,UAAA,QAAQ,KAAK,GAAG;AAClB,QAAAA,MAAAA,cAAc,KAAK,GAAG;AAClB,YAAA,cAAc,aAAa,KAAK,CAAC,MAAM,EAAE,eAAe,KAAK,CAAC;AAEpE,UAAI,aAAa;AACR,eAAA,YAAY,MAAM,KAAK;AAAA,MAAA;AAAA,IAChC;AAGK,WAAA;AAAA,EAAA,CACR;AAAA,EACH,QAAQ,CAAC,UAAe;AAElB,QAAA,MAAM,QAAQ,KAAK,GAAG;AACxB,aAAO,MAAM,IAAI,CAAC,MAAM,mBAAmB,OAAO,CAAC,CAAC;AAAA,IAAA;AAGlD,QAAAA,MAAAA,cAAc,KAAK,GAAG;AACxB,aAAO,OAAO;AAAA,QACZ,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM;AAAA,UACtC;AAAA,UACA,mBAAmB,OAAO,CAAC;AAAA,QAC5B,CAAA;AAAA,MACH;AAAA,IAAA;AAGI,UAAA,cAAc,aAAa,KAAK,CAAC,MAAM,EAAE,mBAAmB,KAAK,CAAC;AACxE,QAAI,aAAa;AACR,aAAA,YAAY,UAAU,KAAK;AAAA,IAAA;AAG7B,WAAA;AAAA,EACT;AAAA,EACA,QAAQ,CAAC,UAAe;AAElB,QAAAA,MAAAA,cAAc,KAAK,GAAG;AAClB,YAAA,cAAc,aAAa,KAAK,CAAC,MAAM,EAAE,eAAe,KAAK,CAAC;AACpE,UAAI,aAAa;AACR,eAAA,YAAY,MAAM,KAAK;AAAA,MAAA;AAAA,IAChC;AAGE,QAAA,MAAM,QAAQ,KAAK,GAAG;AACxB,aAAO,MAAM,IAAI,CAAC,MAAM,mBAAmB,OAAO,CAAC,CAAC;AAAA,IAAA;AAGlD,QAAAA,MAAAA,cAAc,KAAK,GAAG;AACxB,aAAO,OAAO;AAAA,QACZ,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM;AAAA,UACtC;AAAA,UACA,mBAAmB,OAAO,CAAC;AAAA,QAC5B,CAAA;AAAA,MACH;AAAA,IAAA;AAGK,WAAA;AAAA,EAAA;AAEX;AAEA,MAAM,oBAAoB,CACxB,KACA,OACA,UAA+B,CAAC,MAAM,GACtC,YAAiC,CAAC,MAAM,OACpC;AAAA,EACJ;AAAA,EACA,oBAAoB;AAAA,EACpB,WAAW,CAAC,WAAgB,EAAE,CAAC,IAAI,GAAG,EAAE,GAAG,QAAQ,KAAK;EACxD,gBAAgB,CAAC,UAAe,OAAO,OAAO,OAAO,IAAI,GAAG,EAAE;AAAA,EAC9D,OAAO,CAAC,UAAe,UAAU,MAAM,IAAI,GAAG,EAAE,CAAC;AACnD;AAGA,MAAM,eAAe;AAAA,EACnB;AAAA;AAAA,IAEE;AAAA;AAAA,IAEA,CAAC,MAAM,MAAM;AAAA;AAAA,IAEb,MAAM;AAAA;AAAA,IAEN,MAAM;AAAA,EACR;AAAA,EACA;AAAA;AAAA,IAEE;AAAA;AAAA,IAEA,CAAC,MAAM,aAAa;AAAA;AAAA,IAEpB,CAAC,MAAM,EAAE,YAAY;AAAA;AAAA,IAErB,CAAC,MAAM,IAAI,KAAK,CAAC;AAAA,EACnB;AAAA,EACA;AAAA;AAAA,IAEE;AAAA;AAAA,IAEA,CAAC,MAAM,aAAa;AAAA;AAAA,IAEpB,CAAC,OAAO,EAAE,GAAG,GAAG,SAAS,EAAE,SAAS,OAAO,EAAE,OAAO,OAAO,EAAE,MAAM;AAAA;AAAA,IAEnE,CAAC,MAAM,OAAO,OAAO,IAAI,MAAM,EAAE,OAAO,GAAG,CAAC;AAAA,EAAA;AAEhD;;"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export interface RouterTransformer {
|
|
2
2
|
stringify: (obj: unknown) => string;
|
|
3
3
|
parse: (str: string) => unknown;
|
|
4
|
+
encode: <T>(value: T) => T;
|
|
5
|
+
decode: <T>(value: T) => T;
|
|
4
6
|
}
|
|
5
7
|
export declare const defaultTransformer: RouterTransformer;
|
|
6
8
|
export type TransformerStringify<T, TSerializable> = T extends TSerializable ? T : T extends (...args: Array<any>) => any ? 'Function is not serializable' : {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export interface RouterTransformer {
|
|
2
2
|
stringify: (obj: unknown) => string;
|
|
3
3
|
parse: (str: string) => unknown;
|
|
4
|
+
encode: <T>(value: T) => T;
|
|
5
|
+
decode: <T>(value: T) => T;
|
|
4
6
|
}
|
|
5
7
|
export declare const defaultTransformer: RouterTransformer;
|
|
6
8
|
export type TransformerStringify<T, TSerializable> = T extends TSerializable ? T : T extends (...args: Array<any>) => any ? 'Function is not serializable' : {
|
package/dist/esm/transformer.js
CHANGED
|
@@ -1,37 +1,100 @@
|
|
|
1
1
|
import { isPlainObject } from "./utils.js";
|
|
2
2
|
const defaultTransformer = {
|
|
3
|
-
stringify: (value) => JSON.stringify(value, function replacer(key,
|
|
4
|
-
const
|
|
5
|
-
const transformer = transformers.find((t) => t.stringifyCondition(
|
|
3
|
+
stringify: (value) => JSON.stringify(value, function replacer(key, val) {
|
|
4
|
+
const ogVal = this[key];
|
|
5
|
+
const transformer = transformers.find((t) => t.stringifyCondition(ogVal));
|
|
6
6
|
if (transformer) {
|
|
7
|
-
return transformer.stringify(
|
|
7
|
+
return transformer.stringify(ogVal);
|
|
8
8
|
}
|
|
9
|
-
return
|
|
9
|
+
return val;
|
|
10
10
|
}),
|
|
11
|
-
parse: (value) => JSON.parse(value, function parser(key,
|
|
12
|
-
const
|
|
13
|
-
|
|
11
|
+
parse: (value) => JSON.parse(value, function parser(key, val) {
|
|
12
|
+
const ogVal = this[key];
|
|
13
|
+
if (isPlainObject(ogVal)) {
|
|
14
|
+
const transformer = transformers.find((t) => t.parseCondition(ogVal));
|
|
15
|
+
if (transformer) {
|
|
16
|
+
return transformer.parse(ogVal);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return val;
|
|
20
|
+
}),
|
|
21
|
+
encode: (value) => {
|
|
22
|
+
if (Array.isArray(value)) {
|
|
23
|
+
return value.map((v) => defaultTransformer.encode(v));
|
|
24
|
+
}
|
|
25
|
+
if (isPlainObject(value)) {
|
|
26
|
+
return Object.fromEntries(
|
|
27
|
+
Object.entries(value).map(([key, v]) => [
|
|
28
|
+
key,
|
|
29
|
+
defaultTransformer.encode(v)
|
|
30
|
+
])
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const transformer = transformers.find((t) => t.stringifyCondition(value));
|
|
14
34
|
if (transformer) {
|
|
15
|
-
return transformer.
|
|
35
|
+
return transformer.stringify(value);
|
|
16
36
|
}
|
|
17
|
-
return
|
|
18
|
-
})
|
|
19
|
-
};
|
|
20
|
-
const transformers = [
|
|
21
|
-
{
|
|
22
|
-
// Dates
|
|
23
|
-
stringifyCondition: (value) => value instanceof Date,
|
|
24
|
-
stringify: (value) => ({ $date: value.toISOString() }),
|
|
25
|
-
parseCondition: (value) => isPlainObject(value) && value.$date,
|
|
26
|
-
parse: (value) => new Date(value.$date)
|
|
37
|
+
return value;
|
|
27
38
|
},
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
decode: (value) => {
|
|
40
|
+
if (isPlainObject(value)) {
|
|
41
|
+
const transformer = transformers.find((t) => t.parseCondition(value));
|
|
42
|
+
if (transformer) {
|
|
43
|
+
return transformer.parse(value);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(value)) {
|
|
47
|
+
return value.map((v) => defaultTransformer.decode(v));
|
|
48
|
+
}
|
|
49
|
+
if (isPlainObject(value)) {
|
|
50
|
+
return Object.fromEntries(
|
|
51
|
+
Object.entries(value).map(([key, v]) => [
|
|
52
|
+
key,
|
|
53
|
+
defaultTransformer.decode(v)
|
|
54
|
+
])
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
34
58
|
}
|
|
59
|
+
};
|
|
60
|
+
const createTransformer = (key, check, toValue = (v) => v, fromValue = (v) => v) => ({
|
|
61
|
+
key,
|
|
62
|
+
stringifyCondition: check,
|
|
63
|
+
stringify: (value) => ({ [`$${key}`]: toValue(value) }),
|
|
64
|
+
parseCondition: (value) => Object.hasOwn(value, `$${key}`),
|
|
65
|
+
parse: (value) => fromValue(value[`$${key}`])
|
|
66
|
+
});
|
|
67
|
+
const transformers = [
|
|
68
|
+
createTransformer(
|
|
69
|
+
// Key
|
|
70
|
+
"undefined",
|
|
71
|
+
// Check
|
|
72
|
+
(v) => v === void 0,
|
|
73
|
+
// To
|
|
74
|
+
() => 0,
|
|
75
|
+
// From
|
|
76
|
+
() => void 0
|
|
77
|
+
),
|
|
78
|
+
createTransformer(
|
|
79
|
+
// Key
|
|
80
|
+
"date",
|
|
81
|
+
// Check
|
|
82
|
+
(v) => v instanceof Date,
|
|
83
|
+
// To
|
|
84
|
+
(v) => v.toISOString(),
|
|
85
|
+
// From
|
|
86
|
+
(v) => new Date(v)
|
|
87
|
+
),
|
|
88
|
+
createTransformer(
|
|
89
|
+
// Key
|
|
90
|
+
"error",
|
|
91
|
+
// Check
|
|
92
|
+
(v) => v instanceof Error,
|
|
93
|
+
// To
|
|
94
|
+
(v) => ({ ...v, message: v.message, stack: v.stack, cause: v.cause }),
|
|
95
|
+
// From
|
|
96
|
+
(v) => Object.assign(new Error(v.message), v)
|
|
97
|
+
)
|
|
35
98
|
];
|
|
36
99
|
export {
|
|
37
100
|
defaultTransformer
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformer.js","sources":["../../src/transformer.ts"],"sourcesContent":["import { isPlainObject } from './utils'\n\nexport interface RouterTransformer {\n stringify: (obj: unknown) => string\n parse: (str: string) => unknown\n}\n\nexport const defaultTransformer: RouterTransformer = {\n stringify: (value: any) =>\n JSON.stringify(value, function replacer(key,
|
|
1
|
+
{"version":3,"file":"transformer.js","sources":["../../src/transformer.ts"],"sourcesContent":["import { isPlainObject } from './utils'\n\nexport interface RouterTransformer {\n stringify: (obj: unknown) => string\n parse: (str: string) => unknown\n encode: <T>(value: T) => T\n decode: <T>(value: T) => T\n}\n\nexport const defaultTransformer: RouterTransformer = {\n stringify: (value: any) =>\n JSON.stringify(value, function replacer(key, val) {\n const ogVal = this[key]\n const transformer = transformers.find((t) => t.stringifyCondition(ogVal))\n\n if (transformer) {\n return transformer.stringify(ogVal)\n }\n\n return val\n }),\n parse: (value: string) =>\n JSON.parse(value, function parser(key, val) {\n const ogVal = this[key]\n if (isPlainObject(ogVal)) {\n const transformer = transformers.find((t) => t.parseCondition(ogVal))\n\n if (transformer) {\n return transformer.parse(ogVal)\n }\n }\n\n return val\n }),\n encode: (value: any) => {\n // When encodign, dive first\n if (Array.isArray(value)) {\n return value.map((v) => defaultTransformer.encode(v))\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [\n key,\n defaultTransformer.encode(v),\n ]),\n )\n }\n\n const transformer = transformers.find((t) => t.stringifyCondition(value))\n if (transformer) {\n return transformer.stringify(value)\n }\n\n return value\n },\n decode: (value: any) => {\n // Attempt transform first\n if (isPlainObject(value)) {\n const transformer = transformers.find((t) => t.parseCondition(value))\n if (transformer) {\n return transformer.parse(value)\n }\n }\n\n if (Array.isArray(value)) {\n return value.map((v) => defaultTransformer.decode(v))\n }\n\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, v]) => [\n key,\n defaultTransformer.decode(v),\n ]),\n )\n }\n\n return value\n },\n}\n\nconst createTransformer = <T extends string>(\n key: T,\n check: (value: any) => boolean,\n toValue: (value: any) => any = (v) => v,\n fromValue: (value: any) => any = (v) => v,\n) => ({\n key,\n stringifyCondition: check,\n stringify: (value: any) => ({ [`$${key}`]: toValue(value) }),\n parseCondition: (value: any) => Object.hasOwn(value, `$${key}`),\n parse: (value: any) => fromValue(value[`$${key}`]),\n})\n\n// Keep these ordered by predicted frequency\nconst transformers = [\n createTransformer(\n // Key\n 'undefined',\n // Check\n (v) => v === undefined,\n // To\n () => 0,\n // From\n () => undefined,\n ),\n createTransformer(\n // Key\n 'date',\n // Check\n (v) => v instanceof Date,\n // To\n (v) => v.toISOString(),\n // From\n (v) => new Date(v),\n ),\n createTransformer(\n // Key\n 'error',\n // Check\n (v) => v instanceof Error,\n // To\n (v) => ({ ...v, message: v.message, stack: v.stack, cause: v.cause }),\n // From\n (v) => Object.assign(new Error(v.message), v),\n ),\n] as const\n\nexport type TransformerStringify<T, TSerializable> = T extends TSerializable\n ? T\n : T extends (...args: Array<any>) => any\n ? 'Function is not serializable'\n : { [K in keyof T]: TransformerStringify<T[K], TSerializable> }\n\nexport type TransformerParse<T, TSerializable> = T extends TSerializable\n ? T\n : T extends React.JSX.Element\n ? ReadableStream\n : { [K in keyof T]: TransformerParse<T[K], TSerializable> }\n\nexport type DefaultTransformerStringify<T> = TransformerStringify<\n T,\n Date | undefined\n>\n\nexport type DefaultTransformerParse<T> = TransformerParse<T, Date | undefined>\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/transformer.ts
CHANGED
|
@@ -3,49 +3,128 @@ import { isPlainObject } from './utils'
|
|
|
3
3
|
export interface RouterTransformer {
|
|
4
4
|
stringify: (obj: unknown) => string
|
|
5
5
|
parse: (str: string) => unknown
|
|
6
|
+
encode: <T>(value: T) => T
|
|
7
|
+
decode: <T>(value: T) => T
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
export const defaultTransformer: RouterTransformer = {
|
|
9
11
|
stringify: (value: any) =>
|
|
10
|
-
JSON.stringify(value, function replacer(key,
|
|
11
|
-
const
|
|
12
|
-
const transformer = transformers.find((t) => t.stringifyCondition(
|
|
12
|
+
JSON.stringify(value, function replacer(key, val) {
|
|
13
|
+
const ogVal = this[key]
|
|
14
|
+
const transformer = transformers.find((t) => t.stringifyCondition(ogVal))
|
|
13
15
|
|
|
14
16
|
if (transformer) {
|
|
15
|
-
return transformer.stringify(
|
|
17
|
+
return transformer.stringify(ogVal)
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
return
|
|
20
|
+
return val
|
|
19
21
|
}),
|
|
20
22
|
parse: (value: string) =>
|
|
21
|
-
JSON.parse(value, function parser(key,
|
|
22
|
-
const
|
|
23
|
-
|
|
23
|
+
JSON.parse(value, function parser(key, val) {
|
|
24
|
+
const ogVal = this[key]
|
|
25
|
+
if (isPlainObject(ogVal)) {
|
|
26
|
+
const transformer = transformers.find((t) => t.parseCondition(ogVal))
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
28
|
+
if (transformer) {
|
|
29
|
+
return transformer.parse(ogVal)
|
|
30
|
+
}
|
|
27
31
|
}
|
|
28
32
|
|
|
29
|
-
return
|
|
33
|
+
return val
|
|
30
34
|
}),
|
|
31
|
-
|
|
35
|
+
encode: (value: any) => {
|
|
36
|
+
// When encodign, dive first
|
|
37
|
+
if (Array.isArray(value)) {
|
|
38
|
+
return value.map((v) => defaultTransformer.encode(v))
|
|
39
|
+
}
|
|
32
40
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
if (isPlainObject(value)) {
|
|
42
|
+
return Object.fromEntries(
|
|
43
|
+
Object.entries(value).map(([key, v]) => [
|
|
44
|
+
key,
|
|
45
|
+
defaultTransformer.encode(v),
|
|
46
|
+
]),
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const transformer = transformers.find((t) => t.stringifyCondition(value))
|
|
51
|
+
if (transformer) {
|
|
52
|
+
return transformer.stringify(value)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return value
|
|
40
56
|
},
|
|
41
|
-
{
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
decode: (value: any) => {
|
|
58
|
+
// Attempt transform first
|
|
59
|
+
if (isPlainObject(value)) {
|
|
60
|
+
const transformer = transformers.find((t) => t.parseCondition(value))
|
|
61
|
+
if (transformer) {
|
|
62
|
+
return transformer.parse(value)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (Array.isArray(value)) {
|
|
67
|
+
return value.map((v) => defaultTransformer.decode(v))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (isPlainObject(value)) {
|
|
71
|
+
return Object.fromEntries(
|
|
72
|
+
Object.entries(value).map(([key, v]) => [
|
|
73
|
+
key,
|
|
74
|
+
defaultTransformer.decode(v),
|
|
75
|
+
]),
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return value
|
|
48
80
|
},
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const createTransformer = <T extends string>(
|
|
84
|
+
key: T,
|
|
85
|
+
check: (value: any) => boolean,
|
|
86
|
+
toValue: (value: any) => any = (v) => v,
|
|
87
|
+
fromValue: (value: any) => any = (v) => v,
|
|
88
|
+
) => ({
|
|
89
|
+
key,
|
|
90
|
+
stringifyCondition: check,
|
|
91
|
+
stringify: (value: any) => ({ [`$${key}`]: toValue(value) }),
|
|
92
|
+
parseCondition: (value: any) => Object.hasOwn(value, `$${key}`),
|
|
93
|
+
parse: (value: any) => fromValue(value[`$${key}`]),
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
// Keep these ordered by predicted frequency
|
|
97
|
+
const transformers = [
|
|
98
|
+
createTransformer(
|
|
99
|
+
// Key
|
|
100
|
+
'undefined',
|
|
101
|
+
// Check
|
|
102
|
+
(v) => v === undefined,
|
|
103
|
+
// To
|
|
104
|
+
() => 0,
|
|
105
|
+
// From
|
|
106
|
+
() => undefined,
|
|
107
|
+
),
|
|
108
|
+
createTransformer(
|
|
109
|
+
// Key
|
|
110
|
+
'date',
|
|
111
|
+
// Check
|
|
112
|
+
(v) => v instanceof Date,
|
|
113
|
+
// To
|
|
114
|
+
(v) => v.toISOString(),
|
|
115
|
+
// From
|
|
116
|
+
(v) => new Date(v),
|
|
117
|
+
),
|
|
118
|
+
createTransformer(
|
|
119
|
+
// Key
|
|
120
|
+
'error',
|
|
121
|
+
// Check
|
|
122
|
+
(v) => v instanceof Error,
|
|
123
|
+
// To
|
|
124
|
+
(v) => ({ ...v, message: v.message, stack: v.stack, cause: v.cause }),
|
|
125
|
+
// From
|
|
126
|
+
(v) => Object.assign(new Error(v.message), v),
|
|
127
|
+
),
|
|
49
128
|
] as const
|
|
50
129
|
|
|
51
130
|
export type TransformerStringify<T, TSerializable> = T extends TSerializable
|