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