@remix-run/router 1.4.0 → 1.5.0-pre.0
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/CHANGELOG.md +20 -1
- package/dist/index.d.ts +1 -1
- package/dist/router.cjs.js +49 -42
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +15 -8
- package/dist/router.js +49 -42
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +49 -42
- package/dist/router.umd.js.map +1 -1
- package/dist/router.umd.min.js +2 -2
- package/dist/router.umd.min.js.map +1 -1
- package/dist/utils.d.ts +20 -3
- package/index.ts +2 -1
- package/package.json +1 -1
- package/router.ts +93 -58
- package/utils.ts +23 -3
package/dist/utils.d.ts
CHANGED
|
@@ -50,8 +50,25 @@ export interface ErrorResult {
|
|
|
50
50
|
* Result from a loader or action - potentially successful or unsuccessful
|
|
51
51
|
*/
|
|
52
52
|
export declare type DataResult = SuccessResult | DeferredResult | RedirectResult | ErrorResult;
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
declare type LowerCaseFormMethod = "get" | "post" | "put" | "patch" | "delete";
|
|
54
|
+
declare type UpperCaseFormMethod = Uppercase<LowerCaseFormMethod>;
|
|
55
|
+
/**
|
|
56
|
+
* Users can specify either lowercase or uppercase form methods on <Form>,
|
|
57
|
+
* useSubmit(), <fetcher.Form>, etc.
|
|
58
|
+
*/
|
|
59
|
+
export declare type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod;
|
|
60
|
+
/**
|
|
61
|
+
* Active navigation/fetcher form methods are exposed in lowercase on the
|
|
62
|
+
* RouterState
|
|
63
|
+
*/
|
|
64
|
+
export declare type FormMethod = LowerCaseFormMethod;
|
|
65
|
+
export declare type MutationFormMethod = Exclude<FormMethod, "get">;
|
|
66
|
+
/**
|
|
67
|
+
* In v7, active navigation/fetcher form methods are exposed in uppercase on the
|
|
68
|
+
* RouterState. This is to align with the normalization done via fetch().
|
|
69
|
+
*/
|
|
70
|
+
export declare type V7_FormMethod = UpperCaseFormMethod;
|
|
71
|
+
export declare type V7_MutationFormMethod = Exclude<V7_FormMethod, "GET">;
|
|
55
72
|
export declare type FormEncType = "application/x-www-form-urlencoded" | "multipart/form-data";
|
|
56
73
|
/**
|
|
57
74
|
* @private
|
|
@@ -59,7 +76,7 @@ export declare type FormEncType = "application/x-www-form-urlencoded" | "multipa
|
|
|
59
76
|
* external consumption
|
|
60
77
|
*/
|
|
61
78
|
export interface Submission {
|
|
62
|
-
formMethod: FormMethod;
|
|
79
|
+
formMethod: FormMethod | V7_FormMethod;
|
|
63
80
|
formAction: string;
|
|
64
81
|
formEncType: FormEncType;
|
|
65
82
|
formData: FormData;
|
package/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type {
|
|
|
13
13
|
TrackedPromise,
|
|
14
14
|
FormEncType,
|
|
15
15
|
FormMethod,
|
|
16
|
+
HTMLFormMethod,
|
|
16
17
|
JsonFunction,
|
|
17
18
|
LoaderFunction,
|
|
18
19
|
LoaderFunctionArgs,
|
|
@@ -22,7 +23,7 @@ export type {
|
|
|
22
23
|
PathPattern,
|
|
23
24
|
RedirectFunction,
|
|
24
25
|
ShouldRevalidateFunction,
|
|
25
|
-
|
|
26
|
+
V7_FormMethod,
|
|
26
27
|
} from "./utils";
|
|
27
28
|
|
|
28
29
|
export {
|
package/package.json
CHANGED
package/router.ts
CHANGED
|
@@ -22,12 +22,15 @@ import type {
|
|
|
22
22
|
Submission,
|
|
23
23
|
SuccessResult,
|
|
24
24
|
AgnosticRouteMatch,
|
|
25
|
-
MutationFormMethod,
|
|
26
25
|
ShouldRevalidateFunction,
|
|
27
26
|
RouteManifest,
|
|
28
27
|
ImmutableRouteKey,
|
|
29
28
|
ActionFunction,
|
|
30
29
|
LoaderFunction,
|
|
30
|
+
V7_MutationFormMethod,
|
|
31
|
+
V7_FormMethod,
|
|
32
|
+
HTMLFormMethod,
|
|
33
|
+
MutationFormMethod,
|
|
31
34
|
} from "./utils";
|
|
32
35
|
import {
|
|
33
36
|
DeferredData,
|
|
@@ -326,15 +329,23 @@ export type HydrationState = Partial<
|
|
|
326
329
|
Pick<RouterState, "loaderData" | "actionData" | "errors">
|
|
327
330
|
>;
|
|
328
331
|
|
|
332
|
+
/**
|
|
333
|
+
* Future flags to toggle new feature behavior
|
|
334
|
+
*/
|
|
335
|
+
export interface FutureConfig {
|
|
336
|
+
v7_normalizeFormMethod: boolean;
|
|
337
|
+
}
|
|
338
|
+
|
|
329
339
|
/**
|
|
330
340
|
* Initialization options for createRouter
|
|
331
341
|
*/
|
|
332
342
|
export interface RouterInit {
|
|
333
|
-
basename?: string;
|
|
334
343
|
routes: AgnosticRouteObject[];
|
|
335
344
|
history: History;
|
|
336
|
-
|
|
345
|
+
basename?: string;
|
|
337
346
|
detectErrorBoundary?: DetectErrorBoundaryFunction;
|
|
347
|
+
future?: FutureConfig;
|
|
348
|
+
hydrationData?: HydrationState;
|
|
338
349
|
}
|
|
339
350
|
|
|
340
351
|
/**
|
|
@@ -415,7 +426,7 @@ type SubmissionNavigateOptions = {
|
|
|
415
426
|
replace?: boolean;
|
|
416
427
|
state?: any;
|
|
417
428
|
preventScrollReset?: boolean;
|
|
418
|
-
formMethod?:
|
|
429
|
+
formMethod?: HTMLFormMethod;
|
|
419
430
|
formEncType?: FormEncType;
|
|
420
431
|
formData: FormData;
|
|
421
432
|
};
|
|
@@ -449,7 +460,7 @@ export type NavigationStates = {
|
|
|
449
460
|
Loading: {
|
|
450
461
|
state: "loading";
|
|
451
462
|
location: Location;
|
|
452
|
-
formMethod: FormMethod | undefined;
|
|
463
|
+
formMethod: FormMethod | V7_FormMethod | undefined;
|
|
453
464
|
formAction: string | undefined;
|
|
454
465
|
formEncType: FormEncType | undefined;
|
|
455
466
|
formData: FormData | undefined;
|
|
@@ -457,7 +468,7 @@ export type NavigationStates = {
|
|
|
457
468
|
Submitting: {
|
|
458
469
|
state: "submitting";
|
|
459
470
|
location: Location;
|
|
460
|
-
formMethod: FormMethod;
|
|
471
|
+
formMethod: FormMethod | V7_FormMethod;
|
|
461
472
|
formAction: string;
|
|
462
473
|
formEncType: FormEncType;
|
|
463
474
|
formData: FormData;
|
|
@@ -483,7 +494,7 @@ type FetcherStates<TData = any> = {
|
|
|
483
494
|
};
|
|
484
495
|
Loading: {
|
|
485
496
|
state: "loading";
|
|
486
|
-
formMethod: FormMethod | undefined;
|
|
497
|
+
formMethod: FormMethod | V7_FormMethod | undefined;
|
|
487
498
|
formAction: string | undefined;
|
|
488
499
|
formEncType: FormEncType | undefined;
|
|
489
500
|
formData: FormData | undefined;
|
|
@@ -492,7 +503,7 @@ type FetcherStates<TData = any> = {
|
|
|
492
503
|
};
|
|
493
504
|
Submitting: {
|
|
494
505
|
state: "submitting";
|
|
495
|
-
formMethod: FormMethod;
|
|
506
|
+
formMethod: FormMethod | V7_FormMethod;
|
|
496
507
|
formAction: string;
|
|
497
508
|
formEncType: FormEncType;
|
|
498
509
|
formData: FormData;
|
|
@@ -676,6 +687,11 @@ export function createRouter(init: RouterInit): Router {
|
|
|
676
687
|
manifest
|
|
677
688
|
);
|
|
678
689
|
let inFlightDataRoutes: AgnosticDataRouteObject[] | undefined;
|
|
690
|
+
// Config driven behavior flags
|
|
691
|
+
let future: FutureConfig = {
|
|
692
|
+
v7_normalizeFormMethod: false,
|
|
693
|
+
...init.future,
|
|
694
|
+
};
|
|
679
695
|
// Cleanup function for history
|
|
680
696
|
let unlistenHistory: (() => void) | null = null;
|
|
681
697
|
// Externally-provided functions to call on all state changes
|
|
@@ -862,35 +878,15 @@ export function createRouter(init: RouterInit): Router {
|
|
|
862
878
|
}
|
|
863
879
|
);
|
|
864
880
|
|
|
865
|
-
if
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
if (lazyMatches.length === 0) {
|
|
872
|
-
// Kick off initial data load if needed. Use Pop to avoid modifying history
|
|
881
|
+
// Kick off initial data load if needed. Use Pop to avoid modifying history
|
|
882
|
+
// Note we don't do any handling of lazy here. For SPA's it'll get handled
|
|
883
|
+
// in the normal navigation flow. For SSR it's expected that lazy modules are
|
|
884
|
+
// resolved prior to router creation since we can't go into a fallbackElement
|
|
885
|
+
// UI for SSR'd apps
|
|
886
|
+
if (!state.initialized) {
|
|
873
887
|
startNavigation(HistoryAction.Pop, state.location);
|
|
874
|
-
return router;
|
|
875
888
|
}
|
|
876
889
|
|
|
877
|
-
// Load lazy modules, then kick off initial data load if needed
|
|
878
|
-
let lazyPromises = lazyMatches.map((m) =>
|
|
879
|
-
loadLazyRouteModule(m.route, detectErrorBoundary, manifest)
|
|
880
|
-
);
|
|
881
|
-
Promise.all(lazyPromises).then(() => {
|
|
882
|
-
let initialized =
|
|
883
|
-
!state.matches.some((m) => m.route.loader) ||
|
|
884
|
-
init.hydrationData != null;
|
|
885
|
-
if (initialized) {
|
|
886
|
-
// We already have required loaderData so we can just set initialized
|
|
887
|
-
updateState({ initialized: true });
|
|
888
|
-
} else {
|
|
889
|
-
// We still need to kick off initial data loads
|
|
890
|
-
startNavigation(HistoryAction.Pop, state.location);
|
|
891
|
-
}
|
|
892
|
-
});
|
|
893
|
-
|
|
894
890
|
return router;
|
|
895
891
|
}
|
|
896
892
|
|
|
@@ -1033,7 +1029,11 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1033
1029
|
return;
|
|
1034
1030
|
}
|
|
1035
1031
|
|
|
1036
|
-
let { path, submission, error } = normalizeNavigateOptions(
|
|
1032
|
+
let { path, submission, error } = normalizeNavigateOptions(
|
|
1033
|
+
to,
|
|
1034
|
+
future,
|
|
1035
|
+
opts
|
|
1036
|
+
);
|
|
1037
1037
|
|
|
1038
1038
|
let currentLocation = state.location;
|
|
1039
1039
|
let nextLocation = createLocation(state.location, path, opts && opts.state);
|
|
@@ -1152,6 +1152,7 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1152
1152
|
location: Location,
|
|
1153
1153
|
opts?: {
|
|
1154
1154
|
submission?: Submission;
|
|
1155
|
+
fetcherSubmission?: Submission;
|
|
1155
1156
|
overrideNavigation?: Navigation;
|
|
1156
1157
|
pendingError?: ErrorResponse;
|
|
1157
1158
|
startUninterruptedRevalidation?: boolean;
|
|
@@ -1263,6 +1264,7 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1263
1264
|
matches,
|
|
1264
1265
|
loadingNavigation,
|
|
1265
1266
|
opts && opts.submission,
|
|
1267
|
+
opts && opts.fetcherSubmission,
|
|
1266
1268
|
opts && opts.replace,
|
|
1267
1269
|
pendingActionData,
|
|
1268
1270
|
pendingError
|
|
@@ -1385,6 +1387,7 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1385
1387
|
matches: AgnosticDataRouteMatch[],
|
|
1386
1388
|
overrideNavigation?: Navigation,
|
|
1387
1389
|
submission?: Submission,
|
|
1390
|
+
fetcherSubmission?: Submission,
|
|
1388
1391
|
replace?: boolean,
|
|
1389
1392
|
pendingActionData?: RouteData,
|
|
1390
1393
|
pendingError?: RouteData
|
|
@@ -1406,19 +1409,20 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1406
1409
|
|
|
1407
1410
|
// If this was a redirect from an action we don't have a "submission" but
|
|
1408
1411
|
// we have it on the loading navigation so use that if available
|
|
1409
|
-
let activeSubmission =
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
loadingNavigation.
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1412
|
+
let activeSubmission =
|
|
1413
|
+
submission || fetcherSubmission
|
|
1414
|
+
? submission || fetcherSubmission
|
|
1415
|
+
: loadingNavigation.formMethod &&
|
|
1416
|
+
loadingNavigation.formAction &&
|
|
1417
|
+
loadingNavigation.formData &&
|
|
1418
|
+
loadingNavigation.formEncType
|
|
1419
|
+
? {
|
|
1420
|
+
formMethod: loadingNavigation.formMethod,
|
|
1421
|
+
formAction: loadingNavigation.formAction,
|
|
1422
|
+
formData: loadingNavigation.formData,
|
|
1423
|
+
formEncType: loadingNavigation.formEncType,
|
|
1424
|
+
}
|
|
1425
|
+
: undefined;
|
|
1422
1426
|
|
|
1423
1427
|
let routesToUse = inFlightDataRoutes || dataRoutes;
|
|
1424
1428
|
let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(
|
|
@@ -1588,7 +1592,12 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1588
1592
|
return;
|
|
1589
1593
|
}
|
|
1590
1594
|
|
|
1591
|
-
let { path, submission } = normalizeNavigateOptions(
|
|
1595
|
+
let { path, submission } = normalizeNavigateOptions(
|
|
1596
|
+
href,
|
|
1597
|
+
future,
|
|
1598
|
+
opts,
|
|
1599
|
+
true
|
|
1600
|
+
);
|
|
1592
1601
|
let match = getTargetMatch(matches, path);
|
|
1593
1602
|
|
|
1594
1603
|
pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;
|
|
@@ -1680,6 +1689,7 @@ export function createRouter(init: RouterInit): Router {
|
|
|
1680
1689
|
updateState({ fetchers: new Map(state.fetchers) });
|
|
1681
1690
|
|
|
1682
1691
|
return startRedirectNavigation(state, actionResult, {
|
|
1692
|
+
submission,
|
|
1683
1693
|
isFetchActionRedirect: true,
|
|
1684
1694
|
});
|
|
1685
1695
|
}
|
|
@@ -2047,6 +2057,22 @@ export function createRouter(init: RouterInit): Router {
|
|
|
2047
2057
|
// Preserve this flag across redirects
|
|
2048
2058
|
preventScrollReset: pendingPreventScrollReset,
|
|
2049
2059
|
});
|
|
2060
|
+
} else if (isFetchActionRedirect) {
|
|
2061
|
+
// For a fetch action redirect, we kick off a new loading navigation
|
|
2062
|
+
// without the fetcher submission, but we send it along for shouldRevalidate
|
|
2063
|
+
await startNavigation(redirectHistoryAction, redirectLocation, {
|
|
2064
|
+
overrideNavigation: {
|
|
2065
|
+
state: "loading",
|
|
2066
|
+
location: redirectLocation,
|
|
2067
|
+
formMethod: undefined,
|
|
2068
|
+
formAction: undefined,
|
|
2069
|
+
formEncType: undefined,
|
|
2070
|
+
formData: undefined,
|
|
2071
|
+
},
|
|
2072
|
+
fetcherSubmission: submission,
|
|
2073
|
+
// Preserve this flag across redirects
|
|
2074
|
+
preventScrollReset: pendingPreventScrollReset,
|
|
2075
|
+
});
|
|
2050
2076
|
} else {
|
|
2051
2077
|
// Otherwise, we kick off a new loading navigation, preserving the
|
|
2052
2078
|
// submission info for the duration of this navigation
|
|
@@ -2461,12 +2487,12 @@ export function createStaticHandler(
|
|
|
2461
2487
|
{ requestContext }: { requestContext?: unknown } = {}
|
|
2462
2488
|
): Promise<StaticHandlerContext | Response> {
|
|
2463
2489
|
let url = new URL(request.url);
|
|
2464
|
-
let method = request.method
|
|
2490
|
+
let method = request.method;
|
|
2465
2491
|
let location = createLocation("", createPath(url), null, "default");
|
|
2466
2492
|
let matches = matchRoutes(dataRoutes, location, basename);
|
|
2467
2493
|
|
|
2468
2494
|
// SSR supports HEAD requests while SPA doesn't
|
|
2469
|
-
if (!isValidMethod(method) && method !== "
|
|
2495
|
+
if (!isValidMethod(method) && method !== "HEAD") {
|
|
2470
2496
|
let error = getInternalRouterError(405, { method });
|
|
2471
2497
|
let { matches: methodNotAllowedMatches, route } =
|
|
2472
2498
|
getShortCircuitMatches(dataRoutes);
|
|
@@ -2543,12 +2569,12 @@ export function createStaticHandler(
|
|
|
2543
2569
|
}: { requestContext?: unknown; routeId?: string } = {}
|
|
2544
2570
|
): Promise<any> {
|
|
2545
2571
|
let url = new URL(request.url);
|
|
2546
|
-
let method = request.method
|
|
2572
|
+
let method = request.method;
|
|
2547
2573
|
let location = createLocation("", createPath(url), null, "default");
|
|
2548
2574
|
let matches = matchRoutes(dataRoutes, location, basename);
|
|
2549
2575
|
|
|
2550
2576
|
// SSR supports HEAD requests while SPA doesn't
|
|
2551
|
-
if (!isValidMethod(method) && method !== "
|
|
2577
|
+
if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") {
|
|
2552
2578
|
throw getInternalRouterError(405, { method });
|
|
2553
2579
|
} else if (!matches) {
|
|
2554
2580
|
throw getInternalRouterError(404, { pathname: location.pathname });
|
|
@@ -2943,6 +2969,7 @@ function isSubmissionNavigation(
|
|
|
2943
2969
|
// URLSearchParams so they behave identically to links with query params
|
|
2944
2970
|
function normalizeNavigateOptions(
|
|
2945
2971
|
to: To,
|
|
2972
|
+
future: FutureConfig,
|
|
2946
2973
|
opts?: RouterNavigateOptions,
|
|
2947
2974
|
isFetcher = false
|
|
2948
2975
|
): {
|
|
@@ -2967,8 +2994,11 @@ function normalizeNavigateOptions(
|
|
|
2967
2994
|
// Create a Submission on non-GET navigations
|
|
2968
2995
|
let submission: Submission | undefined;
|
|
2969
2996
|
if (opts.formData) {
|
|
2997
|
+
let formMethod = opts.formMethod || "get";
|
|
2970
2998
|
submission = {
|
|
2971
|
-
formMethod:
|
|
2999
|
+
formMethod: future.v7_normalizeFormMethod
|
|
3000
|
+
? (formMethod.toUpperCase() as V7_FormMethod)
|
|
3001
|
+
: (formMethod.toLowerCase() as FormMethod),
|
|
2972
3002
|
formAction: stripHashFromPath(path),
|
|
2973
3003
|
formEncType:
|
|
2974
3004
|
(opts && opts.formEncType) || "application/x-www-form-urlencoded",
|
|
@@ -3482,6 +3512,9 @@ function createClientSideRequest(
|
|
|
3482
3512
|
|
|
3483
3513
|
if (submission && isMutationMethod(submission.formMethod)) {
|
|
3484
3514
|
let { formMethod, formEncType, formData } = submission;
|
|
3515
|
+
// Didn't think we needed this but it turns out unlike other methods, patch
|
|
3516
|
+
// won't be properly normalized to uppercase and results in a 405 error.
|
|
3517
|
+
// See: https://fetch.spec.whatwg.org/#concept-method
|
|
3485
3518
|
init.method = formMethod.toUpperCase();
|
|
3486
3519
|
init.body =
|
|
3487
3520
|
formEncType === "application/x-www-form-urlencoded"
|
|
@@ -3851,12 +3884,14 @@ function isQueryRouteResponse(obj: any): obj is QueryRouteResponse {
|
|
|
3851
3884
|
);
|
|
3852
3885
|
}
|
|
3853
3886
|
|
|
3854
|
-
function isValidMethod(method: string): method is FormMethod {
|
|
3855
|
-
return validRequestMethods.has(method as FormMethod);
|
|
3887
|
+
function isValidMethod(method: string): method is FormMethod | V7_FormMethod {
|
|
3888
|
+
return validRequestMethods.has(method.toLowerCase() as FormMethod);
|
|
3856
3889
|
}
|
|
3857
3890
|
|
|
3858
|
-
function isMutationMethod(
|
|
3859
|
-
|
|
3891
|
+
function isMutationMethod(
|
|
3892
|
+
method: string
|
|
3893
|
+
): method is MutationFormMethod | V7_MutationFormMethod {
|
|
3894
|
+
return validMutationMethods.has(method.toLowerCase() as MutationFormMethod);
|
|
3860
3895
|
}
|
|
3861
3896
|
|
|
3862
3897
|
async function resolveDeferredResults(
|
package/utils.ts
CHANGED
|
@@ -63,8 +63,28 @@ export type DataResult =
|
|
|
63
63
|
| RedirectResult
|
|
64
64
|
| ErrorResult;
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
type LowerCaseFormMethod = "get" | "post" | "put" | "patch" | "delete";
|
|
67
|
+
type UpperCaseFormMethod = Uppercase<LowerCaseFormMethod>;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Users can specify either lowercase or uppercase form methods on <Form>,
|
|
71
|
+
* useSubmit(), <fetcher.Form>, etc.
|
|
72
|
+
*/
|
|
73
|
+
export type HTMLFormMethod = LowerCaseFormMethod | UpperCaseFormMethod;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Active navigation/fetcher form methods are exposed in lowercase on the
|
|
77
|
+
* RouterState
|
|
78
|
+
*/
|
|
79
|
+
export type FormMethod = LowerCaseFormMethod;
|
|
80
|
+
export type MutationFormMethod = Exclude<FormMethod, "get">;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* In v7, active navigation/fetcher form methods are exposed in uppercase on the
|
|
84
|
+
* RouterState. This is to align with the normalization done via fetch().
|
|
85
|
+
*/
|
|
86
|
+
export type V7_FormMethod = UpperCaseFormMethod;
|
|
87
|
+
export type V7_MutationFormMethod = Exclude<V7_FormMethod, "GET">;
|
|
68
88
|
|
|
69
89
|
export type FormEncType =
|
|
70
90
|
| "application/x-www-form-urlencoded"
|
|
@@ -76,7 +96,7 @@ export type FormEncType =
|
|
|
76
96
|
* external consumption
|
|
77
97
|
*/
|
|
78
98
|
export interface Submission {
|
|
79
|
-
formMethod: FormMethod;
|
|
99
|
+
formMethod: FormMethod | V7_FormMethod;
|
|
80
100
|
formAction: string;
|
|
81
101
|
formEncType: FormEncType;
|
|
82
102
|
formData: FormData;
|