@modern-js/plugin-data-loader 2.5.0-alpha.0 → 2.5.1-alpha.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.
Files changed (39) hide show
  1. package/dist/cjs/cli/create-request.js +3 -14
  2. package/dist/cjs/cli/generate-client.js +4 -0
  3. package/dist/cjs/cli/loader.js +3 -0
  4. package/dist/cjs/server/index.js +200 -19
  5. package/dist/esm/cli/create-request.js +2 -41
  6. package/dist/esm/cli/loader.js +6 -0
  7. package/dist/esm/server/index.js +447 -29
  8. package/dist/esm-node/cli/create-request.js +3 -14
  9. package/dist/esm-node/cli/loader.js +3 -0
  10. package/dist/esm-node/server/index.js +196 -21
  11. package/dist/js/modern/cli/create-request.js +66 -0
  12. package/dist/js/modern/cli/generate-client.js +42 -0
  13. package/dist/js/modern/cli/loader.js +40 -0
  14. package/dist/js/modern/common/constants.js +6 -0
  15. package/dist/js/modern/server/index.js +237 -0
  16. package/dist/js/node/cli/create-request.js +90 -0
  17. package/dist/js/node/cli/generate-client.js +71 -0
  18. package/dist/js/node/cli/loader.js +61 -0
  19. package/dist/js/node/common/constants.js +30 -0
  20. package/dist/js/node/server/index.js +261 -0
  21. package/dist/js/treeshaking/cli/create-request.js +186 -0
  22. package/dist/js/treeshaking/cli/generate-client.js +45 -0
  23. package/dist/js/treeshaking/cli/loader.js +154 -0
  24. package/dist/js/treeshaking/common/constants.js +3 -0
  25. package/dist/{esm/runtime → js/treeshaking/server}/index.js +222 -66
  26. package/dist/types/cli/create-request.d.ts +1 -2
  27. package/dist/types/server/index.d.ts +15 -0
  28. package/package.json +10 -21
  29. package/dist/cjs/cli/data.js +0 -162
  30. package/dist/cjs/runtime/index.js +0 -159
  31. package/dist/cjs/runtime/response.js +0 -102
  32. package/dist/esm/cli/data.js +0 -820
  33. package/dist/esm/runtime/response.js +0 -284
  34. package/dist/esm-node/cli/data.js +0 -142
  35. package/dist/esm-node/runtime/index.js +0 -143
  36. package/dist/esm-node/runtime/response.js +0 -79
  37. package/dist/types/cli/data.d.ts +0 -6
  38. package/dist/types/runtime/index.d.ts +0 -15
  39. package/dist/types/runtime/response.d.ts +0 -2
@@ -1,9 +1,194 @@
1
1
  import path from "path";
2
2
  import {
3
- MAIN_ENTRY_NAME,
4
- SERVER_BUNDLE_DIRECTORY
5
- } from "@modern-js/utils";
6
- import { matchEntry } from "../runtime";
3
+ installGlobals,
4
+ writeReadableStreamToWritable,
5
+ Response as NodeResponse
6
+ } from "@remix-run/node";
7
+ import {
8
+ matchRoutes
9
+ } from "react-router-dom";
10
+ import { MAIN_ENTRY_NAME, SERVER_BUNDLE_DIRECTORY } from "@modern-js/utils";
11
+ import { LOADER_ID_PARAM } from "../common/constants";
12
+ installGlobals();
13
+ const redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
14
+ function sortByUrlPath(entries) {
15
+ entries.sort(function(a, b) {
16
+ const length1 = a.urlPath.length;
17
+ const length2 = b.urlPath.length;
18
+ if (length1 < length2) {
19
+ return 1;
20
+ }
21
+ if (length1 > length2) {
22
+ return -1;
23
+ }
24
+ return 0;
25
+ });
26
+ return entries;
27
+ }
28
+ function isRedirectResponse(response) {
29
+ return redirectStatusCodes.has(response.status);
30
+ }
31
+ function isResponse(value) {
32
+ return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
33
+ }
34
+ const json = (data, init = {}) => {
35
+ const responseInit = typeof init === "number" ? { status: init } : init;
36
+ const headers = new Headers(responseInit.headers);
37
+ if (!headers.has("Content-Type")) {
38
+ headers.set("Content-Type", "application/json; charset=utf-8");
39
+ }
40
+ return new NodeResponse(JSON.stringify(data), {
41
+ ...responseInit,
42
+ headers
43
+ });
44
+ };
45
+ const callRouteLoader = async ({
46
+ routeId,
47
+ loader,
48
+ params,
49
+ request,
50
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
51
+ loadContext
52
+ }) => {
53
+ if (!loader) {
54
+ throw new Error(
55
+ `You made a ${request.method} request to ${request.url} but did not provide a default component or \`loader\` for route "${routeId}", so there is no way to handle the request.`
56
+ );
57
+ }
58
+ let result;
59
+ try {
60
+ result = await loader({
61
+ request,
62
+ params
63
+ });
64
+ } catch (error) {
65
+ if (!isResponse(error)) {
66
+ throw error;
67
+ }
68
+ result = error;
69
+ }
70
+ if (result === void 0) {
71
+ throw new Error(
72
+ `You defined a loader for route "${routeId}" but didn't return anything from your \`loader\` function. Please return a value or \`null\`.`
73
+ );
74
+ }
75
+ return isResponse(result) ? result : json(result);
76
+ };
77
+ const createLoaderHeaders = (requestHeaders) => {
78
+ const headers = new Headers();
79
+ for (const [key, values] of Object.entries(requestHeaders)) {
80
+ if (values) {
81
+ if (Array.isArray(values)) {
82
+ for (const value of values) {
83
+ headers.append(key, value);
84
+ }
85
+ } else {
86
+ headers.set(key, values);
87
+ }
88
+ }
89
+ }
90
+ return headers;
91
+ };
92
+ const createLoaderRequest = (context) => {
93
+ const origin = `${context.protocol}://${context.host}`;
94
+ const url = new URL(context.url, origin);
95
+ const controller = new AbortController();
96
+ const init = {
97
+ method: context.method,
98
+ headers: createLoaderHeaders(context.headers),
99
+ signal: controller.signal
100
+ };
101
+ return new Request(url.href, init);
102
+ };
103
+ const sendLoaderResponse = async (res, nodeResponse) => {
104
+ res.statusMessage = nodeResponse.statusText;
105
+ res.statusCode = nodeResponse.status;
106
+ for (const [key, value] of nodeResponse.headers.entries()) {
107
+ res.setHeader(key, value);
108
+ }
109
+ if (nodeResponse.body) {
110
+ await writeReadableStreamToWritable(nodeResponse.body, res);
111
+ } else {
112
+ res.end();
113
+ }
114
+ };
115
+ const getPathWithoutEntry = (pathname, entryPath) => {
116
+ if (entryPath === "/") {
117
+ return pathname;
118
+ }
119
+ return pathname.replace(entryPath, "");
120
+ };
121
+ const matchEntry = (pathname, entries) => {
122
+ const newEntries = sortByUrlPath(entries);
123
+ return newEntries.find((entry) => pathname.startsWith(entry.urlPath));
124
+ };
125
+ const handleRequest = async ({
126
+ context,
127
+ serverRoutes,
128
+ distDir
129
+ }) => {
130
+ const { method, query } = context;
131
+ const routeId = query[LOADER_ID_PARAM];
132
+ if (!routeId || method.toLowerCase() !== "get") {
133
+ return;
134
+ }
135
+ const entry = matchEntry(context.path, serverRoutes);
136
+ if (!entry) {
137
+ return;
138
+ }
139
+ const routesPath = path.join(
140
+ distDir,
141
+ SERVER_BUNDLE_DIRECTORY,
142
+ `${entry.entryName || MAIN_ENTRY_NAME}-server-loaders`
143
+ );
144
+ const { routes } = await import(routesPath);
145
+ if (!routes) {
146
+ return;
147
+ }
148
+ const { res } = context;
149
+ const pathname = getPathWithoutEntry(context.path, entry.urlPath);
150
+ const matches = matchRoutes(routes, pathname);
151
+ if (!matches) {
152
+ res.statusCode = 403;
153
+ res.end(`Route ${pathname} was not matched`);
154
+ return;
155
+ }
156
+ const match = matches == null ? void 0 : matches.find((match2) => match2.route.id === routeId);
157
+ if (!match) {
158
+ res.statusCode = 403;
159
+ res.end(`Route ${routeId} does not match URL ${context.path}`);
160
+ return;
161
+ }
162
+ const request = createLoaderRequest(context);
163
+ let response;
164
+ try {
165
+ response = await callRouteLoader({
166
+ loader: match.route.loader,
167
+ routeId: match.route.id,
168
+ params: match.params,
169
+ request,
170
+ loadContext: {}
171
+ });
172
+ if (isRedirectResponse(response)) {
173
+ const headers = new Headers(response.headers);
174
+ headers.set("X-Modernjs-Redirect", headers.get("Location"));
175
+ headers.delete("Location");
176
+ response = new NodeResponse(null, {
177
+ status: 204,
178
+ headers
179
+ });
180
+ }
181
+ } catch (error) {
182
+ const message = String(error);
183
+ response = new NodeResponse(message, {
184
+ status: 500,
185
+ headers: {
186
+ "Content-Type": "text/plain"
187
+ }
188
+ });
189
+ }
190
+ sendLoaderResponse(res, response);
191
+ };
7
192
  var server_default = () => ({
8
193
  name: "@modern-js/plugin-data-loader",
9
194
  setup: () => ({
@@ -12,29 +197,19 @@ var server_default = () => ({
12
197
  distDir
13
198
  }) {
14
199
  return async (context) => {
15
- const entry = matchEntry(context.path, serverRoutes);
16
- if (!entry) {
17
- throw new Error("Route is not matched");
18
- }
19
- const routesPath = path.join(
20
- distDir,
21
- SERVER_BUNDLE_DIRECTORY,
22
- `${entry.entryName || MAIN_ENTRY_NAME}-server-loaders`
23
- );
24
- const { routes, handleRequest } = await import(routesPath);
25
- if (!routes) {
26
- throw new Error("Missing route info");
27
- ;
28
- }
29
200
  return handleRequest({
30
201
  serverRoutes,
31
- context,
32
- routes
202
+ distDir,
203
+ context
33
204
  });
34
205
  };
35
206
  }
36
207
  })
37
208
  });
38
209
  export {
39
- server_default as default
210
+ server_default as default,
211
+ getPathWithoutEntry,
212
+ handleRequest,
213
+ isRedirectResponse,
214
+ isResponse
40
215
  };
@@ -0,0 +1,66 @@
1
+ var __async = (__this, __arguments, generator) => {
2
+ return new Promise((resolve, reject) => {
3
+ var fulfilled = (value) => {
4
+ try {
5
+ step(generator.next(value));
6
+ } catch (e) {
7
+ reject(e);
8
+ }
9
+ };
10
+ var rejected = (value) => {
11
+ try {
12
+ step(generator.throw(value));
13
+ } catch (e) {
14
+ reject(e);
15
+ }
16
+ };
17
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
18
+ step((generator = generator.apply(__this, __arguments)).next());
19
+ });
20
+ };
21
+ import { compile } from "path-to-regexp";
22
+ import { redirect } from "react-router-dom";
23
+ import { LOADER_ID_PARAM, DIRECT_PARAM } from "../common/constants";
24
+ const getRequestUrl = ({
25
+ params,
26
+ request,
27
+ routeId
28
+ }) => {
29
+ const url = new URL(request.url);
30
+ const toPath = compile(url.pathname, {
31
+ encode: encodeURIComponent
32
+ });
33
+ const newPathName = toPath(params);
34
+ url.pathname = newPathName;
35
+ url.searchParams.append(LOADER_ID_PARAM, routeId);
36
+ url.searchParams.append(DIRECT_PARAM, "true");
37
+ return url;
38
+ };
39
+ const handleRedirectResponse = (res) => {
40
+ const { headers } = res;
41
+ const location = headers.get("X-Modernjs-Redirect");
42
+ if (location) {
43
+ return redirect(location);
44
+ }
45
+ return res;
46
+ };
47
+ const createRequest = (routeId, method = "get") => {
48
+ return (_0) => __async(void 0, [_0], function* ({
49
+ params,
50
+ request
51
+ }) {
52
+ const url = getRequestUrl({ params, request, routeId });
53
+ const res = yield fetch(url, {
54
+ method,
55
+ signal: request.signal
56
+ });
57
+ if (!res.ok) {
58
+ throw res;
59
+ }
60
+ return handleRedirectResponse(res);
61
+ });
62
+ };
63
+ export {
64
+ createRequest,
65
+ getRequestUrl
66
+ };
@@ -0,0 +1,42 @@
1
+ import path from "path";
2
+ const generateClient = ({
3
+ mapFile,
4
+ loaderId
5
+ }) => {
6
+ delete require.cache[mapFile];
7
+ const loadersMap = require(mapFile);
8
+ let requestCode = ``;
9
+ let exportsCode = ``;
10
+ const requestCreatorPath = path.join(__dirname, "./create-request").replace("/node/cli/", "/treeshaking/cli/").replace(/\\/g, "/");
11
+ const importCode = `
12
+ import { createRequest } from '${requestCreatorPath}';
13
+ `;
14
+ if (!loaderId) {
15
+ requestCode = Object.keys(loadersMap).map((loaderId2) => {
16
+ const { routeId } = loadersMap[loaderId2];
17
+ return `
18
+ const ${loaderId2} = createRequest('${routeId}');
19
+ `;
20
+ }).join("");
21
+ exportsCode = `export {`;
22
+ for (const loader of Object.keys(loadersMap)) {
23
+ exportsCode += `${loader},`;
24
+ }
25
+ exportsCode += "}";
26
+ } else {
27
+ const loader = loadersMap[loaderId];
28
+ requestCode = `
29
+ const loader = createRequest('${loader.routeId}');
30
+ `;
31
+ exportsCode = `export default loader;`;
32
+ }
33
+ const generatedCode = `
34
+ ${importCode}
35
+ ${requestCode}
36
+ ${exportsCode}
37
+ `;
38
+ return generatedCode;
39
+ };
40
+ export {
41
+ generateClient
42
+ };
@@ -0,0 +1,40 @@
1
+ var __async = (__this, __arguments, generator) => {
2
+ return new Promise((resolve, reject) => {
3
+ var fulfilled = (value) => {
4
+ try {
5
+ step(generator.next(value));
6
+ } catch (e) {
7
+ reject(e);
8
+ }
9
+ };
10
+ var rejected = (value) => {
11
+ try {
12
+ step(generator.throw(value));
13
+ } catch (e) {
14
+ reject(e);
15
+ }
16
+ };
17
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
18
+ step((generator = generator.apply(__this, __arguments)).next());
19
+ });
20
+ };
21
+ import { generateClient } from "./generate-client";
22
+ function loader(source) {
23
+ return __async(this, null, function* () {
24
+ var _a;
25
+ this.cacheable();
26
+ const target = (_a = this._compiler) == null ? void 0 : _a.options.target;
27
+ if (target === "node") {
28
+ return source;
29
+ }
30
+ const options = this.getOptions();
31
+ const code = generateClient({
32
+ mapFile: options.mapFile,
33
+ loaderId: options.loaderId
34
+ });
35
+ return code;
36
+ });
37
+ }
38
+ export {
39
+ loader as default
40
+ };
@@ -0,0 +1,6 @@
1
+ const LOADER_ID_PARAM = "__loader";
2
+ const DIRECT_PARAM = "__ssrDirect";
3
+ export {
4
+ DIRECT_PARAM,
5
+ LOADER_ID_PARAM
6
+ };
@@ -0,0 +1,237 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __async = (__this, __arguments, generator) => {
21
+ return new Promise((resolve, reject) => {
22
+ var fulfilled = (value) => {
23
+ try {
24
+ step(generator.next(value));
25
+ } catch (e) {
26
+ reject(e);
27
+ }
28
+ };
29
+ var rejected = (value) => {
30
+ try {
31
+ step(generator.throw(value));
32
+ } catch (e) {
33
+ reject(e);
34
+ }
35
+ };
36
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
+ step((generator = generator.apply(__this, __arguments)).next());
38
+ });
39
+ };
40
+ import path from "path";
41
+ import {
42
+ installGlobals,
43
+ writeReadableStreamToWritable,
44
+ Response as NodeResponse
45
+ } from "@remix-run/node";
46
+ import {
47
+ matchRoutes
48
+ } from "react-router-dom";
49
+ import { MAIN_ENTRY_NAME, SERVER_BUNDLE_DIRECTORY } from "@modern-js/utils";
50
+ import { LOADER_ID_PARAM } from "../common/constants";
51
+ installGlobals();
52
+ const redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
53
+ function isRedirectResponse(response) {
54
+ return redirectStatusCodes.has(response.status);
55
+ }
56
+ function isResponse(value) {
57
+ return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
58
+ }
59
+ const json = (data, init = {}) => {
60
+ const responseInit = typeof init === "number" ? { status: init } : init;
61
+ const headers = new Headers(responseInit.headers);
62
+ if (!headers.has("Content-Type")) {
63
+ headers.set("Content-Type", "application/json; charset=utf-8");
64
+ }
65
+ return new NodeResponse(JSON.stringify(data), __spreadProps(__spreadValues({}, responseInit), {
66
+ headers
67
+ }));
68
+ };
69
+ const callRouteLoader = (_0) => __async(void 0, [_0], function* ({
70
+ routeId,
71
+ loader,
72
+ params,
73
+ request,
74
+ loadContext
75
+ }) {
76
+ if (!loader) {
77
+ throw new Error(
78
+ `You made a ${request.method} request to ${request.url} but did not provide a default component or \`loader\` for route "${routeId}", so there is no way to handle the request.`
79
+ );
80
+ }
81
+ let result;
82
+ try {
83
+ result = yield loader({
84
+ request,
85
+ params
86
+ });
87
+ } catch (error) {
88
+ if (!isResponse(error)) {
89
+ throw error;
90
+ }
91
+ result = error;
92
+ }
93
+ if (result === void 0) {
94
+ throw new Error(
95
+ `You defined a loader for route "${routeId}" but didn't return anything from your \`loader\` function. Please return a value or \`null\`.`
96
+ );
97
+ }
98
+ return isResponse(result) ? result : json(result);
99
+ });
100
+ const createLoaderHeaders = (requestHeaders) => {
101
+ const headers = new Headers();
102
+ for (const [key, values] of Object.entries(requestHeaders)) {
103
+ if (values) {
104
+ if (Array.isArray(values)) {
105
+ for (const value of values) {
106
+ headers.append(key, value);
107
+ }
108
+ } else {
109
+ headers.set(key, values);
110
+ }
111
+ }
112
+ }
113
+ return headers;
114
+ };
115
+ const createLoaderRequest = (context) => {
116
+ const origin = `${context.protocol}://${context.host}`;
117
+ const url = new URL(context.url, origin);
118
+ const controller = new AbortController();
119
+ const init = {
120
+ method: context.method,
121
+ headers: createLoaderHeaders(context.headers),
122
+ signal: controller.signal
123
+ };
124
+ return new Request(url.href, init);
125
+ };
126
+ const sendLoaderResponse = (res, nodeResponse) => __async(void 0, null, function* () {
127
+ res.statusMessage = nodeResponse.statusText;
128
+ res.statusCode = nodeResponse.status;
129
+ for (const [key, value] of nodeResponse.headers.entries()) {
130
+ res.setHeader(key, value);
131
+ }
132
+ if (nodeResponse.body) {
133
+ yield writeReadableStreamToWritable(nodeResponse.body, res);
134
+ } else {
135
+ res.end();
136
+ }
137
+ });
138
+ const getPathWithoutEntry = (pathname, entryPath) => {
139
+ if (entryPath === "/") {
140
+ return pathname;
141
+ }
142
+ return pathname.replace(entryPath, "");
143
+ };
144
+ const matchEntry = (pathname, entries) => {
145
+ return entries.find((entry) => pathname.startsWith(entry.urlPath));
146
+ };
147
+ const handleRequest = (_0) => __async(void 0, [_0], function* ({
148
+ context,
149
+ serverRoutes,
150
+ distDir
151
+ }) {
152
+ const { method, query } = context;
153
+ const routeId = query[LOADER_ID_PARAM];
154
+ if (!routeId || method.toLowerCase() !== "get") {
155
+ return;
156
+ }
157
+ const entry = matchEntry(context.path, serverRoutes);
158
+ if (!entry) {
159
+ return;
160
+ }
161
+ const routesPath = path.join(
162
+ distDir,
163
+ SERVER_BUNDLE_DIRECTORY,
164
+ `${entry.entryName || MAIN_ENTRY_NAME}-server-loaders`
165
+ );
166
+ const { routes } = yield import(routesPath);
167
+ if (!routes) {
168
+ return;
169
+ }
170
+ const { res } = context;
171
+ const pathname = getPathWithoutEntry(context.path, entry.urlPath);
172
+ const matches = matchRoutes(routes, pathname);
173
+ if (!matches) {
174
+ res.statusCode = 403;
175
+ res.end(`Route ${pathname} was not matched`);
176
+ return;
177
+ }
178
+ const match = matches == null ? void 0 : matches.find((match2) => match2.route.id === routeId);
179
+ if (!match) {
180
+ res.statusCode = 403;
181
+ res.end(`Route ${routeId} does not match URL ${context.path}`);
182
+ return;
183
+ }
184
+ const request = createLoaderRequest(context);
185
+ let response;
186
+ try {
187
+ response = yield callRouteLoader({
188
+ loader: match.route.loader,
189
+ routeId: match.route.id,
190
+ params: match.params,
191
+ request,
192
+ loadContext: {}
193
+ });
194
+ if (isRedirectResponse(response)) {
195
+ const headers = new Headers(response.headers);
196
+ headers.set("X-Modernjs-Redirect", headers.get("Location"));
197
+ headers.delete("Location");
198
+ response = new NodeResponse(null, {
199
+ status: 204,
200
+ headers
201
+ });
202
+ }
203
+ } catch (error) {
204
+ const message = String(error);
205
+ response = new NodeResponse(message, {
206
+ status: 500,
207
+ headers: {
208
+ "Content-Type": "text/plain"
209
+ }
210
+ });
211
+ }
212
+ sendLoaderResponse(res, response);
213
+ });
214
+ var server_default = () => ({
215
+ name: "@modern-js/plugin-data-loader",
216
+ setup: () => ({
217
+ preparebeforeRouteHandler({
218
+ serverRoutes,
219
+ distDir
220
+ }) {
221
+ return (context) => __async(this, null, function* () {
222
+ return handleRequest({
223
+ serverRoutes,
224
+ distDir,
225
+ context
226
+ });
227
+ });
228
+ }
229
+ })
230
+ });
231
+ export {
232
+ server_default as default,
233
+ getPathWithoutEntry,
234
+ handleRequest,
235
+ isRedirectResponse,
236
+ isResponse
237
+ };