@modern-js/plugin-data-loader 0.0.0-next-20230224023631 → 0.0.0-next-20230224025154
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 +6 -7
- package/dist/cjs/cli/{create-request.js → createRequest.js} +6 -17
- package/dist/cjs/cli/{generate-client.js → generateClient.js} +4 -4
- package/dist/cjs/cli/loader.js +2 -2
- package/dist/cjs/server/index.js +181 -22
- package/dist/esm/cli/{create-request.js → createRequest.js} +2 -41
- package/dist/esm/cli/{generate-client.js → generateClient.js} +1 -1
- package/dist/esm/cli/loader.js +1 -1
- package/dist/esm/server/index.js +432 -38
- package/dist/esm-node/cli/{create-request.js → createRequest.js} +3 -14
- 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/server/index.js +181 -21
- package/dist/types/cli/{create-request.d.ts → createRequest.d.ts} +1 -2
- package/dist/types/server/index.d.ts +15 -0
- package/package.json +9 -20
- package/dist/cjs/cli/data.js +0 -162
- package/dist/cjs/runtime/index.js +0 -165
- package/dist/cjs/runtime/response.js +0 -102
- package/dist/esm/cli/data.js +0 -820
- package/dist/esm/runtime/index.js +0 -427
- package/dist/esm/runtime/response.js +0 -284
- package/dist/esm-node/cli/data.js +0 -142
- package/dist/esm-node/runtime/index.js +0 -147
- package/dist/esm-node/runtime/response.js +0 -79
- package/dist/types/cli/data.d.ts +0 -6
- package/dist/types/runtime/index.d.ts +0 -15
- package/dist/types/runtime/response.d.ts +0 -2
- /package/dist/types/cli/{generate-client.d.ts → generateClient.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# @modern-js/plugin-data-loader
|
|
2
2
|
|
|
3
|
-
## 0.0.0-next-
|
|
3
|
+
## 0.0.0-next-20230224025154
|
|
4
4
|
|
|
5
|
-
###
|
|
5
|
+
### Patch Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
feat: 流式渲染支持 deferred data
|
|
7
|
+
- 7fff9020e1: chore: make file naming consistent
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
chore: 统一文件命名为小驼峰格式
|
|
11
10
|
|
|
12
|
-
- Updated dependencies [
|
|
13
|
-
- @modern-js/utils@0.0.0-next-
|
|
11
|
+
- Updated dependencies [7fff9020e1]
|
|
12
|
+
- @modern-js/utils@0.0.0-next-20230224025154
|
|
@@ -15,16 +15,15 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
15
|
return to;
|
|
16
16
|
};
|
|
17
17
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
-
var
|
|
19
|
-
__export(
|
|
18
|
+
var createRequest_exports = {};
|
|
19
|
+
__export(createRequest_exports, {
|
|
20
20
|
createRequest: () => createRequest,
|
|
21
21
|
getRequestUrl: () => getRequestUrl
|
|
22
22
|
});
|
|
23
|
-
module.exports = __toCommonJS(
|
|
23
|
+
module.exports = __toCommonJS(createRequest_exports);
|
|
24
24
|
var import_path_to_regexp = require("path-to-regexp");
|
|
25
25
|
var import_react_router_dom = require("react-router-dom");
|
|
26
26
|
var import_constants = require("../common/constants");
|
|
27
|
-
var import_data = require("./data");
|
|
28
27
|
const getRequestUrl = ({
|
|
29
28
|
params,
|
|
30
29
|
request,
|
|
@@ -44,14 +43,7 @@ const handleRedirectResponse = (res) => {
|
|
|
44
43
|
const { headers } = res;
|
|
45
44
|
const location = headers.get("X-Modernjs-Redirect");
|
|
46
45
|
if (location) {
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
return res;
|
|
50
|
-
};
|
|
51
|
-
const handleDeferredResponse = async (res) => {
|
|
52
|
-
var _a;
|
|
53
|
-
if (((_a = res.headers.get("Content-Type")) == null ? void 0 : _a.match(/text\/modernjs-deferred/)) && res.body) {
|
|
54
|
-
return await (0, import_data.parseDeferredReadableStream)(res.body);
|
|
46
|
+
return (0, import_react_router_dom.redirect)(location);
|
|
55
47
|
}
|
|
56
48
|
return res;
|
|
57
49
|
};
|
|
@@ -61,17 +53,14 @@ const createRequest = (routeId, method = "get") => {
|
|
|
61
53
|
request
|
|
62
54
|
}) => {
|
|
63
55
|
const url = getRequestUrl({ params, request, routeId });
|
|
64
|
-
|
|
65
|
-
res = await fetch(url, {
|
|
56
|
+
const res = await fetch(url, {
|
|
66
57
|
method,
|
|
67
58
|
signal: request.signal
|
|
68
59
|
});
|
|
69
60
|
if (!res.ok) {
|
|
70
61
|
throw res;
|
|
71
62
|
}
|
|
72
|
-
|
|
73
|
-
res = await handleDeferredResponse(res);
|
|
74
|
-
return res;
|
|
63
|
+
return handleRedirectResponse(res);
|
|
75
64
|
};
|
|
76
65
|
};
|
|
77
66
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -25,11 +25,11 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
25
25
|
mod
|
|
26
26
|
));
|
|
27
27
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
var
|
|
29
|
-
__export(
|
|
28
|
+
var generateClient_exports = {};
|
|
29
|
+
__export(generateClient_exports, {
|
|
30
30
|
generateClient: () => generateClient
|
|
31
31
|
});
|
|
32
|
-
module.exports = __toCommonJS(
|
|
32
|
+
module.exports = __toCommonJS(generateClient_exports);
|
|
33
33
|
var import_path = __toESM(require("path"));
|
|
34
34
|
const generateClient = ({
|
|
35
35
|
mapFile,
|
|
@@ -39,7 +39,7 @@ const generateClient = ({
|
|
|
39
39
|
const loadersMap = require(mapFile);
|
|
40
40
|
let requestCode = ``;
|
|
41
41
|
let exportsCode = ``;
|
|
42
|
-
const requestCreatorPath = import_path.default.join(__dirname, "./
|
|
42
|
+
const requestCreatorPath = import_path.default.join(__dirname, "./createRequest").replace("/cjs/cli/", "/esm/cli/").replace(/\\/g, "/");
|
|
43
43
|
const importCode = `
|
|
44
44
|
import { createRequest } from '${requestCreatorPath}';
|
|
45
45
|
`;
|
package/dist/cjs/cli/loader.js
CHANGED
|
@@ -20,7 +20,7 @@ __export(loader_exports, {
|
|
|
20
20
|
default: () => loader
|
|
21
21
|
});
|
|
22
22
|
module.exports = __toCommonJS(loader_exports);
|
|
23
|
-
var
|
|
23
|
+
var import_generateClient = require("./generateClient");
|
|
24
24
|
async function loader(source) {
|
|
25
25
|
var _a;
|
|
26
26
|
this.cacheable();
|
|
@@ -32,7 +32,7 @@ async function loader(source) {
|
|
|
32
32
|
return source;
|
|
33
33
|
}
|
|
34
34
|
const options = this.getOptions();
|
|
35
|
-
const code = (0,
|
|
35
|
+
const code = (0, import_generateClient.generateClient)({
|
|
36
36
|
mapFile: options.mapFile,
|
|
37
37
|
loaderId: options.loaderId
|
|
38
38
|
});
|
package/dist/cjs/server/index.js
CHANGED
|
@@ -27,13 +27,183 @@ 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
|
|
30
|
+
default: () => server_default,
|
|
31
|
+
getPathWithoutEntry: () => getPathWithoutEntry,
|
|
32
|
+
handleRequest: () => handleRequest,
|
|
33
|
+
isRedirectResponse: () => isRedirectResponse,
|
|
34
|
+
isResponse: () => isResponse
|
|
31
35
|
});
|
|
32
36
|
module.exports = __toCommonJS(server_exports);
|
|
33
37
|
var import_path = __toESM(require("path"));
|
|
34
|
-
var
|
|
38
|
+
var import_node = require("@remix-run/node");
|
|
39
|
+
var import_react_router_dom = require("react-router-dom");
|
|
35
40
|
var import_utils = require("@modern-js/utils");
|
|
36
|
-
var
|
|
41
|
+
var import_constants = require("../common/constants");
|
|
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
|
+
};
|
|
37
207
|
var server_default = () => ({
|
|
38
208
|
name: "@modern-js/plugin-data-loader",
|
|
39
209
|
setup: () => ({
|
|
@@ -42,30 +212,19 @@ var server_default = () => ({
|
|
|
42
212
|
distDir
|
|
43
213
|
}) {
|
|
44
214
|
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
|
-
}
|
|
61
215
|
return handleRequest({
|
|
62
216
|
serverRoutes,
|
|
63
|
-
|
|
64
|
-
|
|
217
|
+
distDir,
|
|
218
|
+
context
|
|
65
219
|
});
|
|
66
220
|
};
|
|
67
221
|
}
|
|
68
222
|
})
|
|
69
223
|
});
|
|
70
224
|
// Annotate the CommonJS export names for ESM import in node:
|
|
71
|
-
0 && (module.exports = {
|
|
225
|
+
0 && (module.exports = {
|
|
226
|
+
getPathWithoutEntry,
|
|
227
|
+
handleRequest,
|
|
228
|
+
isRedirectResponse,
|
|
229
|
+
isResponse
|
|
230
|
+
});
|
|
@@ -125,7 +125,6 @@ var __generator = this && this.__generator || function(thisArg, body) {
|
|
|
125
125
|
import { compile } from "path-to-regexp";
|
|
126
126
|
import { redirect } from "react-router-dom";
|
|
127
127
|
import { LOADER_ID_PARAM, DIRECT_PARAM } from "../common/constants";
|
|
128
|
-
import { parseDeferredReadableStream } from "./data";
|
|
129
128
|
var getRequestUrl = function(param) {
|
|
130
129
|
var params = param.params, request = param.request, routeId = param.routeId;
|
|
131
130
|
var url = new URL(request.url);
|
|
@@ -142,41 +141,10 @@ var handleRedirectResponse = function(res) {
|
|
|
142
141
|
var headers = res.headers;
|
|
143
142
|
var location = headers.get("X-Modernjs-Redirect");
|
|
144
143
|
if (location) {
|
|
145
|
-
|
|
144
|
+
return redirect(location);
|
|
146
145
|
}
|
|
147
146
|
return res;
|
|
148
147
|
};
|
|
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(/text\/modernjs-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
|
-
}();
|
|
180
148
|
var createRequest = function(routeId) {
|
|
181
149
|
var method = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "get";
|
|
182
150
|
return function() {
|
|
@@ -203,16 +171,9 @@ var createRequest = function(routeId) {
|
|
|
203
171
|
if (!res.ok) {
|
|
204
172
|
throw res;
|
|
205
173
|
}
|
|
206
|
-
res = handleRedirectResponse(res);
|
|
207
|
-
return [
|
|
208
|
-
4,
|
|
209
|
-
handleDeferredResponse(res)
|
|
210
|
-
];
|
|
211
|
-
case 2:
|
|
212
|
-
res = _state.sent();
|
|
213
174
|
return [
|
|
214
175
|
2,
|
|
215
|
-
res
|
|
176
|
+
handleRedirectResponse(res)
|
|
216
177
|
];
|
|
217
178
|
}
|
|
218
179
|
});
|
|
@@ -5,7 +5,7 @@ var generateClient = function(param) {
|
|
|
5
5
|
var loadersMap = require(mapFile);
|
|
6
6
|
var requestCode = "";
|
|
7
7
|
var exportsCode = "";
|
|
8
|
-
var requestCreatorPath = path.join(__dirname, "./
|
|
8
|
+
var requestCreatorPath = path.join(__dirname, "./createRequest").replace("/cjs/cli/", "/esm/cli/").replace(/\\/g, "/");
|
|
9
9
|
var importCode = "\n import { createRequest } from '".concat(requestCreatorPath, "';\n ");
|
|
10
10
|
if (!loaderId) {
|
|
11
11
|
requestCode = Object.keys(loadersMap).map(function(loaderId2) {
|
package/dist/esm/cli/loader.js
CHANGED
|
@@ -122,7 +122,7 @@ var __generator = this && this.__generator || function(thisArg, body) {
|
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
124
|
};
|
|
125
|
-
import { generateClient } from "./
|
|
125
|
+
import { generateClient } from "./generateClient";
|
|
126
126
|
function loader(source) {
|
|
127
127
|
return _loader.apply(this, arguments);
|
|
128
128
|
}
|