@tanstack/react-router 1.95.4 → 1.95.5
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/index.d.cts +1 -1
- package/dist/cjs/transformer.cjs +16 -3
- package/dist/cjs/transformer.cjs.map +1 -1
- package/dist/cjs/transformer.d.cts +3 -2
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/transformer.d.ts +3 -2
- package/dist/esm/transformer.js +16 -3
- package/dist/esm/transformer.js.map +1 -1
- package/package.json +1 -1
- package/src/index.tsx +1 -0
- package/src/transformer.ts +37 -15
package/dist/cjs/index.d.cts
CHANGED
|
@@ -42,7 +42,7 @@ export type { ScrollRestorationOptions } from './scroll-restoration.cjs';
|
|
|
42
42
|
export { defaultParseSearch, defaultStringifySearch, parseSearchWith, stringifySearchWith, } from './searchParams.cjs';
|
|
43
43
|
export type { SearchSerializer, SearchParser } from './searchParams.cjs';
|
|
44
44
|
export { defaultTransformer } from './transformer.cjs';
|
|
45
|
-
export type { RouterTransformer, TransformerParse, TransformerStringify, DefaultTransformerParse, DefaultTransformerStringify, } from './transformer.cjs';
|
|
45
|
+
export type { RouterTransformer, TransformerParse, TransformerStringify, DefaultSerializable, DefaultTransformerParse, DefaultTransformerStringify, } from './transformer.cjs';
|
|
46
46
|
export type { UseBlockerOpts, ShouldBlockFn } from './useBlocker.cjs';
|
|
47
47
|
export { useBlocker, Block } from './useBlocker.cjs';
|
|
48
48
|
export { useNavigate, Navigate } from './useNavigate.cjs';
|
package/dist/cjs/transformer.cjs
CHANGED
|
@@ -59,7 +59,7 @@ const defaultTransformer = {
|
|
|
59
59
|
return value;
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
|
-
const createTransformer = (key, check, toValue
|
|
62
|
+
const createTransformer = (key, check, toValue, fromValue) => ({
|
|
63
63
|
key,
|
|
64
64
|
stringifyCondition: check,
|
|
65
65
|
stringify: (value) => ({ [`$${key}`]: toValue(value) }),
|
|
@@ -106,7 +106,16 @@ const transformers = [
|
|
|
106
106
|
(v) => {
|
|
107
107
|
const entries = {};
|
|
108
108
|
v.forEach((value, key) => {
|
|
109
|
-
entries[key]
|
|
109
|
+
const entry = entries[key];
|
|
110
|
+
if (entry !== void 0) {
|
|
111
|
+
if (Array.isArray(entry)) {
|
|
112
|
+
entry.push(value);
|
|
113
|
+
} else {
|
|
114
|
+
entries[key] = [entry, value];
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
entries[key] = value;
|
|
118
|
+
}
|
|
110
119
|
});
|
|
111
120
|
return entries;
|
|
112
121
|
},
|
|
@@ -114,7 +123,11 @@ const transformers = [
|
|
|
114
123
|
(v) => {
|
|
115
124
|
const formData = new FormData();
|
|
116
125
|
Object.entries(v).forEach(([key, value]) => {
|
|
117
|
-
|
|
126
|
+
if (Array.isArray(value)) {
|
|
127
|
+
value.forEach((val) => formData.append(key, val));
|
|
128
|
+
} else {
|
|
129
|
+
formData.append(key, value);
|
|
130
|
+
}
|
|
118
131
|
});
|
|
119
132
|
return formData;
|
|
120
133
|
}
|
|
@@ -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 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 encoding, 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 = <
|
|
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 encoding, 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 = <TKey extends string, TInput, TSerialized>(\n key: TKey,\n check: (value: any) => value is TInput,\n toValue: (value: TInput) => TSerialized,\n fromValue: (value: TSerialized) => TInput,\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\n// Make sure to keep DefaultSerializeable in sync with these transformers\n// Also, make sure that they are unit tested in transformer.test.tsx\nconst transformers = [\n createTransformer(\n // Key\n 'undefined',\n // Check\n (v): v is undefined => v === undefined,\n // To\n () => 0,\n // From\n () => undefined,\n ),\n createTransformer(\n // Key\n 'date',\n // Check\n (v): v is Date => 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 is Error => 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 createTransformer(\n // Key\n 'formData',\n // Check\n (v): v is FormData => v instanceof FormData,\n // To\n (v) => {\n const entries: Record<\n string,\n Array<FormDataEntryValue> | FormDataEntryValue\n > = {}\n v.forEach((value, key) => {\n const entry = entries[key]\n if (entry !== undefined) {\n if (Array.isArray(entry)) {\n entry.push(value)\n } else {\n entries[key] = [entry, value]\n }\n } else {\n entries[key] = value\n }\n })\n return entries\n },\n // From\n (v) => {\n const formData = new FormData()\n Object.entries(v).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((val) => formData.append(key, val))\n } else {\n formData.append(key, value)\n }\n })\n return formData\n },\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 DefaultSerializable = Date | undefined | Error | FormData\n\nexport type DefaultTransformerStringify<T> = TransformerStringify<\n T,\n DefaultSerializable\n>\n\nexport type DefaultTransformerParse<T> = TransformerParse<\n T,\n DefaultSerializable\n>\n"],"names":["isPlainObject"],"mappings":"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"}
|
|
@@ -11,5 +11,6 @@ export type TransformerStringify<T, TSerializable> = T extends TSerializable ? T
|
|
|
11
11
|
export type TransformerParse<T, TSerializable> = T extends TSerializable ? T : T extends React.JSX.Element ? ReadableStream : {
|
|
12
12
|
[K in keyof T]: TransformerParse<T[K], TSerializable>;
|
|
13
13
|
};
|
|
14
|
-
export type
|
|
15
|
-
export type
|
|
14
|
+
export type DefaultSerializable = Date | undefined | Error | FormData;
|
|
15
|
+
export type DefaultTransformerStringify<T> = TransformerStringify<T, DefaultSerializable>;
|
|
16
|
+
export type DefaultTransformerParse<T> = TransformerParse<T, DefaultSerializable>;
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export type { ScrollRestorationOptions } from './scroll-restoration.js';
|
|
|
42
42
|
export { defaultParseSearch, defaultStringifySearch, parseSearchWith, stringifySearchWith, } from './searchParams.js';
|
|
43
43
|
export type { SearchSerializer, SearchParser } from './searchParams.js';
|
|
44
44
|
export { defaultTransformer } from './transformer.js';
|
|
45
|
-
export type { RouterTransformer, TransformerParse, TransformerStringify, DefaultTransformerParse, DefaultTransformerStringify, } from './transformer.js';
|
|
45
|
+
export type { RouterTransformer, TransformerParse, TransformerStringify, DefaultSerializable, DefaultTransformerParse, DefaultTransformerStringify, } from './transformer.js';
|
|
46
46
|
export type { UseBlockerOpts, ShouldBlockFn } from './useBlocker.js';
|
|
47
47
|
export { useBlocker, Block } from './useBlocker.js';
|
|
48
48
|
export { useNavigate, Navigate } from './useNavigate.js';
|
|
@@ -11,5 +11,6 @@ export type TransformerStringify<T, TSerializable> = T extends TSerializable ? T
|
|
|
11
11
|
export type TransformerParse<T, TSerializable> = T extends TSerializable ? T : T extends React.JSX.Element ? ReadableStream : {
|
|
12
12
|
[K in keyof T]: TransformerParse<T[K], TSerializable>;
|
|
13
13
|
};
|
|
14
|
-
export type
|
|
15
|
-
export type
|
|
14
|
+
export type DefaultSerializable = Date | undefined | Error | FormData;
|
|
15
|
+
export type DefaultTransformerStringify<T> = TransformerStringify<T, DefaultSerializable>;
|
|
16
|
+
export type DefaultTransformerParse<T> = TransformerParse<T, DefaultSerializable>;
|
package/dist/esm/transformer.js
CHANGED
|
@@ -57,7 +57,7 @@ const defaultTransformer = {
|
|
|
57
57
|
return value;
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
|
-
const createTransformer = (key, check, toValue
|
|
60
|
+
const createTransformer = (key, check, toValue, fromValue) => ({
|
|
61
61
|
key,
|
|
62
62
|
stringifyCondition: check,
|
|
63
63
|
stringify: (value) => ({ [`$${key}`]: toValue(value) }),
|
|
@@ -104,7 +104,16 @@ const transformers = [
|
|
|
104
104
|
(v) => {
|
|
105
105
|
const entries = {};
|
|
106
106
|
v.forEach((value, key) => {
|
|
107
|
-
entries[key]
|
|
107
|
+
const entry = entries[key];
|
|
108
|
+
if (entry !== void 0) {
|
|
109
|
+
if (Array.isArray(entry)) {
|
|
110
|
+
entry.push(value);
|
|
111
|
+
} else {
|
|
112
|
+
entries[key] = [entry, value];
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
entries[key] = value;
|
|
116
|
+
}
|
|
108
117
|
});
|
|
109
118
|
return entries;
|
|
110
119
|
},
|
|
@@ -112,7 +121,11 @@ const transformers = [
|
|
|
112
121
|
(v) => {
|
|
113
122
|
const formData = new FormData();
|
|
114
123
|
Object.entries(v).forEach(([key, value]) => {
|
|
115
|
-
|
|
124
|
+
if (Array.isArray(value)) {
|
|
125
|
+
value.forEach((val) => formData.append(key, val));
|
|
126
|
+
} else {
|
|
127
|
+
formData.append(key, value);
|
|
128
|
+
}
|
|
116
129
|
});
|
|
117
130
|
return formData;
|
|
118
131
|
}
|
|
@@ -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 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 encoding, 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 = <
|
|
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 encoding, 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 = <TKey extends string, TInput, TSerialized>(\n key: TKey,\n check: (value: any) => value is TInput,\n toValue: (value: TInput) => TSerialized,\n fromValue: (value: TSerialized) => TInput,\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\n// Make sure to keep DefaultSerializeable in sync with these transformers\n// Also, make sure that they are unit tested in transformer.test.tsx\nconst transformers = [\n createTransformer(\n // Key\n 'undefined',\n // Check\n (v): v is undefined => v === undefined,\n // To\n () => 0,\n // From\n () => undefined,\n ),\n createTransformer(\n // Key\n 'date',\n // Check\n (v): v is Date => 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 is Error => 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 createTransformer(\n // Key\n 'formData',\n // Check\n (v): v is FormData => v instanceof FormData,\n // To\n (v) => {\n const entries: Record<\n string,\n Array<FormDataEntryValue> | FormDataEntryValue\n > = {}\n v.forEach((value, key) => {\n const entry = entries[key]\n if (entry !== undefined) {\n if (Array.isArray(entry)) {\n entry.push(value)\n } else {\n entries[key] = [entry, value]\n }\n } else {\n entries[key] = value\n }\n })\n return entries\n },\n // From\n (v) => {\n const formData = new FormData()\n Object.entries(v).forEach(([key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((val) => formData.append(key, val))\n } else {\n formData.append(key, value)\n }\n })\n return formData\n },\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 DefaultSerializable = Date | undefined | Error | FormData\n\nexport type DefaultTransformerStringify<T> = TransformerStringify<\n T,\n DefaultSerializable\n>\n\nexport type DefaultTransformerParse<T> = TransformerParse<\n T,\n DefaultSerializable\n>\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.tsx
CHANGED
package/src/transformer.ts
CHANGED
|
@@ -80,11 +80,11 @@ export const defaultTransformer: RouterTransformer = {
|
|
|
80
80
|
},
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
const createTransformer = <
|
|
84
|
-
key:
|
|
85
|
-
check: (value: any) =>
|
|
86
|
-
toValue: (value:
|
|
87
|
-
fromValue: (value:
|
|
83
|
+
const createTransformer = <TKey extends string, TInput, TSerialized>(
|
|
84
|
+
key: TKey,
|
|
85
|
+
check: (value: any) => value is TInput,
|
|
86
|
+
toValue: (value: TInput) => TSerialized,
|
|
87
|
+
fromValue: (value: TSerialized) => TInput,
|
|
88
88
|
) => ({
|
|
89
89
|
key,
|
|
90
90
|
stringifyCondition: check,
|
|
@@ -94,13 +94,14 @@ const createTransformer = <T extends string>(
|
|
|
94
94
|
})
|
|
95
95
|
|
|
96
96
|
// Keep these ordered by predicted frequency
|
|
97
|
+
// Make sure to keep DefaultSerializeable in sync with these transformers
|
|
97
98
|
// Also, make sure that they are unit tested in transformer.test.tsx
|
|
98
99
|
const transformers = [
|
|
99
100
|
createTransformer(
|
|
100
101
|
// Key
|
|
101
102
|
'undefined',
|
|
102
103
|
// Check
|
|
103
|
-
(v) => v === undefined,
|
|
104
|
+
(v): v is undefined => v === undefined,
|
|
104
105
|
// To
|
|
105
106
|
() => 0,
|
|
106
107
|
// From
|
|
@@ -110,7 +111,7 @@ const transformers = [
|
|
|
110
111
|
// Key
|
|
111
112
|
'date',
|
|
112
113
|
// Check
|
|
113
|
-
(v) => v instanceof Date,
|
|
114
|
+
(v): v is Date => v instanceof Date,
|
|
114
115
|
// To
|
|
115
116
|
(v) => v.toISOString(),
|
|
116
117
|
// From
|
|
@@ -120,7 +121,7 @@ const transformers = [
|
|
|
120
121
|
// Key
|
|
121
122
|
'error',
|
|
122
123
|
// Check
|
|
123
|
-
(v) => v instanceof Error,
|
|
124
|
+
(v): v is Error => v instanceof Error,
|
|
124
125
|
// To
|
|
125
126
|
(v) => ({ ...v, message: v.message, stack: v.stack, cause: v.cause }),
|
|
126
127
|
// From
|
|
@@ -130,12 +131,24 @@ const transformers = [
|
|
|
130
131
|
// Key
|
|
131
132
|
'formData',
|
|
132
133
|
// Check
|
|
133
|
-
(v) => v instanceof FormData,
|
|
134
|
+
(v): v is FormData => v instanceof FormData,
|
|
134
135
|
// To
|
|
135
|
-
(v
|
|
136
|
-
const entries: Record<
|
|
136
|
+
(v) => {
|
|
137
|
+
const entries: Record<
|
|
138
|
+
string,
|
|
139
|
+
Array<FormDataEntryValue> | FormDataEntryValue
|
|
140
|
+
> = {}
|
|
137
141
|
v.forEach((value, key) => {
|
|
138
|
-
entries[key]
|
|
142
|
+
const entry = entries[key]
|
|
143
|
+
if (entry !== undefined) {
|
|
144
|
+
if (Array.isArray(entry)) {
|
|
145
|
+
entry.push(value)
|
|
146
|
+
} else {
|
|
147
|
+
entries[key] = [entry, value]
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
entries[key] = value
|
|
151
|
+
}
|
|
139
152
|
})
|
|
140
153
|
return entries
|
|
141
154
|
},
|
|
@@ -143,7 +156,11 @@ const transformers = [
|
|
|
143
156
|
(v) => {
|
|
144
157
|
const formData = new FormData()
|
|
145
158
|
Object.entries(v).forEach(([key, value]) => {
|
|
146
|
-
|
|
159
|
+
if (Array.isArray(value)) {
|
|
160
|
+
value.forEach((val) => formData.append(key, val))
|
|
161
|
+
} else {
|
|
162
|
+
formData.append(key, value)
|
|
163
|
+
}
|
|
147
164
|
})
|
|
148
165
|
return formData
|
|
149
166
|
},
|
|
@@ -162,9 +179,14 @@ export type TransformerParse<T, TSerializable> = T extends TSerializable
|
|
|
162
179
|
? ReadableStream
|
|
163
180
|
: { [K in keyof T]: TransformerParse<T[K], TSerializable> }
|
|
164
181
|
|
|
182
|
+
export type DefaultSerializable = Date | undefined | Error | FormData
|
|
183
|
+
|
|
165
184
|
export type DefaultTransformerStringify<T> = TransformerStringify<
|
|
166
185
|
T,
|
|
167
|
-
|
|
186
|
+
DefaultSerializable
|
|
168
187
|
>
|
|
169
188
|
|
|
170
|
-
export type DefaultTransformerParse<T> = TransformerParse<
|
|
189
|
+
export type DefaultTransformerParse<T> = TransformerParse<
|
|
190
|
+
T,
|
|
191
|
+
DefaultSerializable
|
|
192
|
+
>
|