@modern-js/plugin-data-loader 2.6.0 → 2.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/dist/cjs/cli/{create-request.js → createRequest.js} +17 -6
- package/dist/cjs/cli/data.js +162 -0
- package/dist/cjs/cli/{generate-client.js → generateClient.js} +4 -4
- package/dist/cjs/cli/loader.js +2 -2
- package/dist/cjs/common/constants.js +3 -0
- package/dist/cjs/runtime/index.js +165 -0
- package/dist/cjs/runtime/response.js +102 -0
- package/dist/cjs/server/index.js +22 -181
- package/dist/esm/cli/{create-request.js → createRequest.js} +42 -3
- package/dist/esm/cli/data.js +820 -0
- package/dist/esm/cli/{generate-client.js → generateClient.js} +1 -1
- package/dist/esm/cli/loader.js +1 -1
- package/dist/esm/common/constants.js +2 -1
- package/dist/esm/runtime/index.js +427 -0
- package/dist/esm/runtime/response.js +284 -0
- package/dist/esm/server/index.js +38 -432
- package/dist/esm-node/cli/{create-request.js → createRequest.js} +19 -4
- package/dist/esm-node/cli/data.js +142 -0
- package/dist/esm-node/cli/{generate-client.js → generateClient.js} +1 -1
- package/dist/esm-node/cli/loader.js +1 -1
- package/dist/esm-node/common/constants.js +2 -0
- package/dist/esm-node/runtime/index.js +147 -0
- package/dist/esm-node/runtime/response.js +79 -0
- package/dist/esm-node/server/index.js +21 -181
- package/dist/types/cli/{create-request.d.ts → createRequest.d.ts} +2 -1
- package/dist/types/cli/data.d.ts +6 -0
- package/dist/types/common/constants.d.ts +2 -1
- package/dist/types/runtime/index.d.ts +15 -0
- package/dist/types/runtime/response.d.ts +2 -0
- package/dist/types/server/index.d.ts +0 -15
- package/package.json +19 -9
- /package/dist/types/cli/{generate-client.d.ts → generateClient.d.ts} +0 -0
package/dist/cjs/server/index.js
CHANGED
|
@@ -27,183 +27,13 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
28
|
var server_exports = {};
|
|
29
29
|
__export(server_exports, {
|
|
30
|
-
default: () => server_default
|
|
31
|
-
getPathWithoutEntry: () => getPathWithoutEntry,
|
|
32
|
-
handleRequest: () => handleRequest,
|
|
33
|
-
isRedirectResponse: () => isRedirectResponse,
|
|
34
|
-
isResponse: () => isResponse
|
|
30
|
+
default: () => server_default
|
|
35
31
|
});
|
|
36
32
|
module.exports = __toCommonJS(server_exports);
|
|
37
33
|
var import_path = __toESM(require("path"));
|
|
38
|
-
var
|
|
39
|
-
var import_react_router_dom = require("react-router-dom");
|
|
34
|
+
var import_fs = __toESM(require("fs"));
|
|
40
35
|
var import_utils = require("@modern-js/utils");
|
|
41
|
-
var
|
|
42
|
-
(0, import_node.installGlobals)();
|
|
43
|
-
const redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
44
|
-
function isRedirectResponse(response) {
|
|
45
|
-
return redirectStatusCodes.has(response.status);
|
|
46
|
-
}
|
|
47
|
-
function isResponse(value) {
|
|
48
|
-
return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
|
|
49
|
-
}
|
|
50
|
-
const json = (data, init = {}) => {
|
|
51
|
-
const responseInit = typeof init === "number" ? { status: init } : init;
|
|
52
|
-
const headers = new Headers(responseInit.headers);
|
|
53
|
-
if (!headers.has("Content-Type")) {
|
|
54
|
-
headers.set("Content-Type", "application/json; charset=utf-8");
|
|
55
|
-
}
|
|
56
|
-
return new import_node.Response(JSON.stringify(data), {
|
|
57
|
-
...responseInit,
|
|
58
|
-
headers
|
|
59
|
-
});
|
|
60
|
-
};
|
|
61
|
-
const callRouteLoader = async ({
|
|
62
|
-
routeId,
|
|
63
|
-
loader,
|
|
64
|
-
params,
|
|
65
|
-
request,
|
|
66
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
67
|
-
loadContext
|
|
68
|
-
}) => {
|
|
69
|
-
if (!loader) {
|
|
70
|
-
throw new Error(
|
|
71
|
-
`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.`
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
let result;
|
|
75
|
-
try {
|
|
76
|
-
result = await loader({
|
|
77
|
-
request,
|
|
78
|
-
params
|
|
79
|
-
});
|
|
80
|
-
} catch (error) {
|
|
81
|
-
if (!isResponse(error)) {
|
|
82
|
-
throw error;
|
|
83
|
-
}
|
|
84
|
-
result = error;
|
|
85
|
-
}
|
|
86
|
-
if (result === void 0) {
|
|
87
|
-
throw new Error(
|
|
88
|
-
`You defined a loader for route "${routeId}" but didn't return anything from your \`loader\` function. Please return a value or \`null\`.`
|
|
89
|
-
);
|
|
90
|
-
}
|
|
91
|
-
return isResponse(result) ? result : json(result);
|
|
92
|
-
};
|
|
93
|
-
const createLoaderHeaders = (requestHeaders) => {
|
|
94
|
-
const headers = new Headers();
|
|
95
|
-
for (const [key, values] of Object.entries(requestHeaders)) {
|
|
96
|
-
if (values) {
|
|
97
|
-
if (Array.isArray(values)) {
|
|
98
|
-
for (const value of values) {
|
|
99
|
-
headers.append(key, value);
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
headers.set(key, values);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return headers;
|
|
107
|
-
};
|
|
108
|
-
const createLoaderRequest = (context) => {
|
|
109
|
-
const origin = `${context.protocol}://${context.host}`;
|
|
110
|
-
const url = new URL(context.url, origin);
|
|
111
|
-
const controller = new AbortController();
|
|
112
|
-
const init = {
|
|
113
|
-
method: context.method,
|
|
114
|
-
headers: createLoaderHeaders(context.headers),
|
|
115
|
-
signal: controller.signal
|
|
116
|
-
};
|
|
117
|
-
return new Request(url.href, init);
|
|
118
|
-
};
|
|
119
|
-
const sendLoaderResponse = async (res, nodeResponse) => {
|
|
120
|
-
res.statusMessage = nodeResponse.statusText;
|
|
121
|
-
res.statusCode = nodeResponse.status;
|
|
122
|
-
for (const [key, value] of nodeResponse.headers.entries()) {
|
|
123
|
-
res.setHeader(key, value);
|
|
124
|
-
}
|
|
125
|
-
if (nodeResponse.body) {
|
|
126
|
-
await (0, import_node.writeReadableStreamToWritable)(nodeResponse.body, res);
|
|
127
|
-
} else {
|
|
128
|
-
res.end();
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
const getPathWithoutEntry = (pathname, entryPath) => {
|
|
132
|
-
if (entryPath === "/") {
|
|
133
|
-
return pathname;
|
|
134
|
-
}
|
|
135
|
-
return pathname.replace(entryPath, "");
|
|
136
|
-
};
|
|
137
|
-
const matchEntry = (pathname, entries) => {
|
|
138
|
-
return entries.find((entry) => pathname.startsWith(entry.urlPath));
|
|
139
|
-
};
|
|
140
|
-
const handleRequest = async ({
|
|
141
|
-
context,
|
|
142
|
-
serverRoutes,
|
|
143
|
-
distDir
|
|
144
|
-
}) => {
|
|
145
|
-
const { method, query } = context;
|
|
146
|
-
const routeId = query[import_constants.LOADER_ID_PARAM];
|
|
147
|
-
if (!routeId || method.toLowerCase() !== "get") {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
const entry = matchEntry(context.path, serverRoutes);
|
|
151
|
-
if (!entry) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
const routesPath = import_path.default.join(
|
|
155
|
-
distDir,
|
|
156
|
-
import_utils.SERVER_BUNDLE_DIRECTORY,
|
|
157
|
-
`${entry.entryName || import_utils.MAIN_ENTRY_NAME}-server-loaders`
|
|
158
|
-
);
|
|
159
|
-
const { routes } = await Promise.resolve().then(() => __toESM(require(routesPath)));
|
|
160
|
-
if (!routes) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
const { res } = context;
|
|
164
|
-
const pathname = getPathWithoutEntry(context.path, entry.urlPath);
|
|
165
|
-
const matches = (0, import_react_router_dom.matchRoutes)(routes, pathname);
|
|
166
|
-
if (!matches) {
|
|
167
|
-
res.statusCode = 403;
|
|
168
|
-
res.end(`Route ${pathname} was not matched`);
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
const match = matches == null ? void 0 : matches.find((match2) => match2.route.id === routeId);
|
|
172
|
-
if (!match) {
|
|
173
|
-
res.statusCode = 403;
|
|
174
|
-
res.end(`Route ${routeId} does not match URL ${context.path}`);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
const request = createLoaderRequest(context);
|
|
178
|
-
let response;
|
|
179
|
-
try {
|
|
180
|
-
response = await callRouteLoader({
|
|
181
|
-
loader: match.route.loader,
|
|
182
|
-
routeId: match.route.id,
|
|
183
|
-
params: match.params,
|
|
184
|
-
request,
|
|
185
|
-
loadContext: {}
|
|
186
|
-
});
|
|
187
|
-
if (isRedirectResponse(response)) {
|
|
188
|
-
const headers = new Headers(response.headers);
|
|
189
|
-
headers.set("X-Modernjs-Redirect", headers.get("Location"));
|
|
190
|
-
headers.delete("Location");
|
|
191
|
-
response = new import_node.Response(null, {
|
|
192
|
-
status: 204,
|
|
193
|
-
headers
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
} catch (error) {
|
|
197
|
-
const message = String(error);
|
|
198
|
-
response = new import_node.Response(message, {
|
|
199
|
-
status: 500,
|
|
200
|
-
headers: {
|
|
201
|
-
"Content-Type": "text/plain"
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
sendLoaderResponse(res, response);
|
|
206
|
-
};
|
|
36
|
+
var import_runtime2 = require("../runtime");
|
|
207
37
|
var server_default = () => ({
|
|
208
38
|
name: "@modern-js/plugin-data-loader",
|
|
209
39
|
setup: () => ({
|
|
@@ -212,19 +42,30 @@ var server_default = () => ({
|
|
|
212
42
|
distDir
|
|
213
43
|
}) {
|
|
214
44
|
return async (context) => {
|
|
45
|
+
const entry = (0, import_runtime2.matchEntry)(context.path, serverRoutes);
|
|
46
|
+
if (!entry) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const routesPath = import_path.default.join(
|
|
50
|
+
distDir,
|
|
51
|
+
import_utils.SERVER_BUNDLE_DIRECTORY,
|
|
52
|
+
`${entry.entryName || import_utils.MAIN_ENTRY_NAME}-server-loaders.js`
|
|
53
|
+
);
|
|
54
|
+
if (!import_fs.default.existsSync(routesPath)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const { routes, handleRequest } = await Promise.resolve().then(() => __toESM(require(routesPath)));
|
|
58
|
+
if (!routes) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
215
61
|
return handleRequest({
|
|
216
62
|
serverRoutes,
|
|
217
|
-
|
|
218
|
-
|
|
63
|
+
context,
|
|
64
|
+
routes
|
|
219
65
|
});
|
|
220
66
|
};
|
|
221
67
|
}
|
|
222
68
|
})
|
|
223
69
|
});
|
|
224
70
|
// Annotate the CommonJS export names for ESM import in node:
|
|
225
|
-
0 && (module.exports = {
|
|
226
|
-
getPathWithoutEntry,
|
|
227
|
-
handleRequest,
|
|
228
|
-
isRedirectResponse,
|
|
229
|
-
isResponse
|
|
230
|
-
});
|
|
71
|
+
0 && (module.exports = {});
|
|
@@ -124,7 +124,8 @@ var __generator = this && this.__generator || function(thisArg, body) {
|
|
|
124
124
|
};
|
|
125
125
|
import { compile } from "path-to-regexp";
|
|
126
126
|
import { redirect } from "react-router-dom";
|
|
127
|
-
import { LOADER_ID_PARAM, DIRECT_PARAM } from "../common/constants";
|
|
127
|
+
import { LOADER_ID_PARAM, DIRECT_PARAM, CONTENT_TYPE_DEFERRED } from "../common/constants";
|
|
128
|
+
import { parseDeferredReadableStream } from "./data";
|
|
128
129
|
var getRequestUrl = function(param) {
|
|
129
130
|
var params = param.params, request = param.request, routeId = param.routeId;
|
|
130
131
|
var url = new URL(request.url);
|
|
@@ -141,10 +142,41 @@ var handleRedirectResponse = function(res) {
|
|
|
141
142
|
var headers = res.headers;
|
|
142
143
|
var location = headers.get("X-Modernjs-Redirect");
|
|
143
144
|
if (location) {
|
|
144
|
-
|
|
145
|
+
throw redirect(location);
|
|
145
146
|
}
|
|
146
147
|
return res;
|
|
147
148
|
};
|
|
149
|
+
var handleDeferredResponse = function() {
|
|
150
|
+
var _ref = _asyncToGenerator(function(res) {
|
|
151
|
+
var _res_headers_get;
|
|
152
|
+
return __generator(this, function(_state) {
|
|
153
|
+
switch(_state.label){
|
|
154
|
+
case 0:
|
|
155
|
+
if (!(((_res_headers_get = res.headers.get("Content-Type")) === null || _res_headers_get === void 0 ? void 0 : _res_headers_get.match(CONTENT_TYPE_DEFERRED)) && res.body)) return [
|
|
156
|
+
3,
|
|
157
|
+
2
|
|
158
|
+
];
|
|
159
|
+
return [
|
|
160
|
+
4,
|
|
161
|
+
parseDeferredReadableStream(res.body)
|
|
162
|
+
];
|
|
163
|
+
case 1:
|
|
164
|
+
return [
|
|
165
|
+
2,
|
|
166
|
+
_state.sent()
|
|
167
|
+
];
|
|
168
|
+
case 2:
|
|
169
|
+
return [
|
|
170
|
+
2,
|
|
171
|
+
res
|
|
172
|
+
];
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
return function handleDeferredResponse(res) {
|
|
177
|
+
return _ref.apply(this, arguments);
|
|
178
|
+
};
|
|
179
|
+
}();
|
|
148
180
|
var createRequest = function(routeId) {
|
|
149
181
|
var method = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "get";
|
|
150
182
|
return function() {
|
|
@@ -171,9 +203,16 @@ var createRequest = function(routeId) {
|
|
|
171
203
|
if (!res.ok) {
|
|
172
204
|
throw res;
|
|
173
205
|
}
|
|
206
|
+
res = handleRedirectResponse(res);
|
|
207
|
+
return [
|
|
208
|
+
4,
|
|
209
|
+
handleDeferredResponse(res)
|
|
210
|
+
];
|
|
211
|
+
case 2:
|
|
212
|
+
res = _state.sent();
|
|
174
213
|
return [
|
|
175
214
|
2,
|
|
176
|
-
|
|
215
|
+
res
|
|
177
216
|
];
|
|
178
217
|
}
|
|
179
218
|
});
|