@tanstack/react-router 1.95.3 → 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 +38 -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,12 +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
|
|
98
|
+
// Also, make sure that they are unit tested in transformer.test.tsx
|
|
97
99
|
const transformers = [
|
|
98
100
|
createTransformer(
|
|
99
101
|
// Key
|
|
100
102
|
'undefined',
|
|
101
103
|
// Check
|
|
102
|
-
(v) => v === undefined,
|
|
104
|
+
(v): v is undefined => v === undefined,
|
|
103
105
|
// To
|
|
104
106
|
() => 0,
|
|
105
107
|
// From
|
|
@@ -109,7 +111,7 @@ const transformers = [
|
|
|
109
111
|
// Key
|
|
110
112
|
'date',
|
|
111
113
|
// Check
|
|
112
|
-
(v) => v instanceof Date,
|
|
114
|
+
(v): v is Date => v instanceof Date,
|
|
113
115
|
// To
|
|
114
116
|
(v) => v.toISOString(),
|
|
115
117
|
// From
|
|
@@ -119,7 +121,7 @@ const transformers = [
|
|
|
119
121
|
// Key
|
|
120
122
|
'error',
|
|
121
123
|
// Check
|
|
122
|
-
(v) => v instanceof Error,
|
|
124
|
+
(v): v is Error => v instanceof Error,
|
|
123
125
|
// To
|
|
124
126
|
(v) => ({ ...v, message: v.message, stack: v.stack, cause: v.cause }),
|
|
125
127
|
// From
|
|
@@ -129,12 +131,24 @@ const transformers = [
|
|
|
129
131
|
// Key
|
|
130
132
|
'formData',
|
|
131
133
|
// Check
|
|
132
|
-
(v) => v instanceof FormData,
|
|
134
|
+
(v): v is FormData => v instanceof FormData,
|
|
133
135
|
// To
|
|
134
|
-
(v
|
|
135
|
-
const entries: Record<
|
|
136
|
+
(v) => {
|
|
137
|
+
const entries: Record<
|
|
138
|
+
string,
|
|
139
|
+
Array<FormDataEntryValue> | FormDataEntryValue
|
|
140
|
+
> = {}
|
|
136
141
|
v.forEach((value, key) => {
|
|
137
|
-
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
|
+
}
|
|
138
152
|
})
|
|
139
153
|
return entries
|
|
140
154
|
},
|
|
@@ -142,7 +156,11 @@ const transformers = [
|
|
|
142
156
|
(v) => {
|
|
143
157
|
const formData = new FormData()
|
|
144
158
|
Object.entries(v).forEach(([key, value]) => {
|
|
145
|
-
|
|
159
|
+
if (Array.isArray(value)) {
|
|
160
|
+
value.forEach((val) => formData.append(key, val))
|
|
161
|
+
} else {
|
|
162
|
+
formData.append(key, value)
|
|
163
|
+
}
|
|
146
164
|
})
|
|
147
165
|
return formData
|
|
148
166
|
},
|
|
@@ -161,9 +179,14 @@ export type TransformerParse<T, TSerializable> = T extends TSerializable
|
|
|
161
179
|
? ReadableStream
|
|
162
180
|
: { [K in keyof T]: TransformerParse<T[K], TSerializable> }
|
|
163
181
|
|
|
182
|
+
export type DefaultSerializable = Date | undefined | Error | FormData
|
|
183
|
+
|
|
164
184
|
export type DefaultTransformerStringify<T> = TransformerStringify<
|
|
165
185
|
T,
|
|
166
|
-
|
|
186
|
+
DefaultSerializable
|
|
167
187
|
>
|
|
168
188
|
|
|
169
|
-
export type DefaultTransformerParse<T> = TransformerParse<
|
|
189
|
+
export type DefaultTransformerParse<T> = TransformerParse<
|
|
190
|
+
T,
|
|
191
|
+
DefaultSerializable
|
|
192
|
+
>
|