@remix-run/router 1.6.3 → 1.7.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/utils.ts CHANGED
@@ -88,19 +88,48 @@ export type V7_MutationFormMethod = Exclude<V7_FormMethod, "GET">;
88
88
 
89
89
  export type FormEncType =
90
90
  | "application/x-www-form-urlencoded"
91
- | "multipart/form-data";
91
+ | "multipart/form-data"
92
+ | "application/json"
93
+ | "text/plain";
94
+
95
+ // Thanks https://github.com/sindresorhus/type-fest!
96
+ type JsonObject = { [Key in string]: JsonValue } & {
97
+ [Key in string]?: JsonValue | undefined;
98
+ };
99
+ type JsonArray = JsonValue[] | readonly JsonValue[];
100
+ type JsonPrimitive = string | number | boolean | null;
101
+ type JsonValue = JsonPrimitive | JsonObject | JsonArray;
92
102
 
93
103
  /**
94
104
  * @private
95
105
  * Internal interface to pass around for action submissions, not intended for
96
106
  * external consumption
97
107
  */
98
- export interface Submission {
99
- formMethod: FormMethod | V7_FormMethod;
100
- formAction: string;
101
- formEncType: FormEncType;
102
- formData: FormData;
103
- }
108
+ export type Submission =
109
+ | {
110
+ formMethod: FormMethod | V7_FormMethod;
111
+ formAction: string;
112
+ formEncType: FormEncType;
113
+ formData: FormData;
114
+ json: undefined;
115
+ text: undefined;
116
+ }
117
+ | {
118
+ formMethod: FormMethod | V7_FormMethod;
119
+ formAction: string;
120
+ formEncType: FormEncType;
121
+ formData: undefined;
122
+ json: JsonValue;
123
+ text: undefined;
124
+ }
125
+ | {
126
+ formMethod: FormMethod | V7_FormMethod;
127
+ formAction: string;
128
+ formEncType: FormEncType;
129
+ formData: undefined;
130
+ json: undefined;
131
+ text: string;
132
+ };
104
133
 
105
134
  /**
106
135
  * @private
@@ -160,7 +189,9 @@ export interface ShouldRevalidateFunction {
160
189
  formMethod?: Submission["formMethod"];
161
190
  formAction?: Submission["formAction"];
162
191
  formEncType?: Submission["formEncType"];
192
+ text?: Submission["text"];
163
193
  formData?: Submission["formData"];
194
+ json?: Submission["json"];
164
195
  actionResult?: DataResult;
165
196
  defaultShouldRevalidate: boolean;
166
197
  }): boolean;
@@ -731,6 +762,9 @@ export function generatePath<Path extends string>(
731
762
  // ensure `/` is added at the beginning if the path is absolute
732
763
  const prefix = path.startsWith("/") ? "/" : "";
733
764
 
765
+ const stringify = (p: any) =>
766
+ p == null ? "" : typeof p === "string" ? p : String(p);
767
+
734
768
  const segments = path
735
769
  .split(/\/+/)
736
770
  .map((segment, index, array) => {
@@ -739,26 +773,16 @@ export function generatePath<Path extends string>(
739
773
  // only apply the splat if it's the last segment
740
774
  if (isLastSegment && segment === "*") {
741
775
  const star = "*" as PathParam<Path>;
742
- const starParam = params[star];
743
-
744
776
  // Apply the splat
745
- return starParam;
777
+ return stringify(params[star]);
746
778
  }
747
779
 
748
780
  const keyMatch = segment.match(/^:(\w+)(\??)$/);
749
781
  if (keyMatch) {
750
782
  const [, key, optional] = keyMatch;
751
783
  let param = params[key as PathParam<Path>];
752
-
753
- if (optional === "?") {
754
- return param == null ? "" : param;
755
- }
756
-
757
- if (param == null) {
758
- invariant(false, `Missing ":${key}" param`);
759
- }
760
-
761
- return param;
784
+ invariant(optional === "?" || param != null, `Missing ":${key}" param`);
785
+ return stringify(param);
762
786
  }
763
787
 
764
788
  // Remove any optional markers from optional static segments