@modern-js/plugin-data-loader 0.0.0-next-20221104140607

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.
@@ -0,0 +1,365 @@
1
+ import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
2
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
3
+ import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
4
+ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
5
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
6
+ import _typeof from "@babel/runtime/helpers/esm/typeof";
7
+ import { installGlobals, writeReadableStreamToWritable, Response as NodeResponse } from '@remix-run/node';
8
+ import { matchRoutes } from 'react-router-dom';
9
+ // Polyfill Web Fetch API
10
+ installGlobals();
11
+ var LOADER_SEARCH_PARAM = '_loader';
12
+ var redirectStatusCodes = new Set([301, 302, 303, 307, 308]);
13
+ export function isRedirectResponse(response) {
14
+ return redirectStatusCodes.has(response.status);
15
+ }
16
+ export function isResponse(value) {
17
+ return value != null && typeof value.status === 'number' && typeof value.statusText === 'string' && _typeof(value.headers) === 'object' && typeof value.body !== 'undefined';
18
+ }
19
+
20
+ var json = function json(data) {
21
+ var init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
22
+ var responseInit = typeof init === 'number' ? {
23
+ status: init
24
+ } : init;
25
+ var headers = new Headers(responseInit.headers);
26
+
27
+ if (!headers.has('Content-Type')) {
28
+ headers.set('Content-Type', 'application/json; charset=utf-8');
29
+ }
30
+
31
+ return new NodeResponse(JSON.stringify(data), _objectSpread(_objectSpread({}, responseInit), {}, {
32
+ headers: headers
33
+ }));
34
+ }; // TODO: 添加 context
35
+
36
+
37
+ var callRouteLoader = /*#__PURE__*/function () {
38
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(_ref) {
39
+ var routeId, loader, params, request, loadContext, result;
40
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
41
+ while (1) {
42
+ switch (_context.prev = _context.next) {
43
+ case 0:
44
+ routeId = _ref.routeId, loader = _ref.loader, params = _ref.params, request = _ref.request, loadContext = _ref.loadContext;
45
+
46
+ if (loader) {
47
+ _context.next = 3;
48
+ break;
49
+ }
50
+
51
+ throw new Error("You made a ".concat(request.method, " request to ").concat(request.url, " but did not provide ") + "a default component or `loader` for route \"".concat(routeId, "\", ") + "so there is no way to handle the request.");
52
+
53
+ case 3:
54
+ _context.prev = 3;
55
+ _context.next = 6;
56
+ return loader({
57
+ request: request,
58
+ params: params
59
+ });
60
+
61
+ case 6:
62
+ result = _context.sent;
63
+ _context.next = 14;
64
+ break;
65
+
66
+ case 9:
67
+ _context.prev = 9;
68
+ _context.t0 = _context["catch"](3);
69
+
70
+ if (isResponse(_context.t0)) {
71
+ _context.next = 13;
72
+ break;
73
+ }
74
+
75
+ throw _context.t0;
76
+
77
+ case 13:
78
+ result = _context.t0;
79
+
80
+ case 14:
81
+ if (!(result === undefined)) {
82
+ _context.next = 16;
83
+ break;
84
+ }
85
+
86
+ throw new Error("You defined a loader for route \"".concat(routeId, "\" but didn't return ") + "anything from your `loader` function. Please return a value or `null`.");
87
+
88
+ case 16:
89
+ return _context.abrupt("return", isResponse(result) ? result : json(result));
90
+
91
+ case 17:
92
+ case "end":
93
+ return _context.stop();
94
+ }
95
+ }
96
+ }, _callee, null, [[3, 9]]);
97
+ }));
98
+
99
+ return function callRouteLoader(_x) {
100
+ return _ref2.apply(this, arguments);
101
+ };
102
+ }();
103
+
104
+ var createLoaderHeaders = function createLoaderHeaders(requestHeaders) {
105
+ var headers = new Headers();
106
+
107
+ for (var _i = 0, _Object$entries = Object.entries(requestHeaders); _i < _Object$entries.length; _i++) {
108
+ var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
109
+ _key = _Object$entries$_i[0],
110
+ values = _Object$entries$_i[1];
111
+
112
+ if (values) {
113
+ if (Array.isArray(values)) {
114
+ var _iterator = _createForOfIteratorHelper(values),
115
+ _step;
116
+
117
+ try {
118
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
119
+ var value = _step.value;
120
+ headers.append(_key, value);
121
+ }
122
+ } catch (err) {
123
+ _iterator.e(err);
124
+ } finally {
125
+ _iterator.f();
126
+ }
127
+ } else {
128
+ headers.set(_key, values);
129
+ }
130
+ }
131
+ }
132
+
133
+ return headers;
134
+ };
135
+
136
+ var createLoaderRequest = function createLoaderRequest(context) {
137
+ var origin = "".concat(context.protocol, "://").concat(context.host); // eslint-disable-next-line node/no-unsupported-features/node-builtins, node/prefer-global/url
138
+
139
+ var url = new URL(context.url, origin);
140
+ var controller = new AbortController();
141
+ var init = {
142
+ method: context.method,
143
+ headers: createLoaderHeaders(context.headers),
144
+ signal: controller.signal
145
+ };
146
+ return new Request(url.href, init);
147
+ };
148
+
149
+ var sendLoaderResponse = /*#__PURE__*/function () {
150
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(res, nodeResponse) {
151
+ var _iterator2, _step2, _step2$value, _key2, value;
152
+
153
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
154
+ while (1) {
155
+ switch (_context2.prev = _context2.next) {
156
+ case 0:
157
+ res.statusMessage = nodeResponse.statusText;
158
+ res.statusCode = nodeResponse.status;
159
+ _iterator2 = _createForOfIteratorHelper(nodeResponse.headers.entries());
160
+
161
+ try {
162
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
163
+ _step2$value = _slicedToArray(_step2.value, 2), _key2 = _step2$value[0], value = _step2$value[1];
164
+ res.setHeader(_key2, value);
165
+ }
166
+ } catch (err) {
167
+ _iterator2.e(err);
168
+ } finally {
169
+ _iterator2.f();
170
+ }
171
+
172
+ if (!nodeResponse.body) {
173
+ _context2.next = 9;
174
+ break;
175
+ }
176
+
177
+ _context2.next = 7;
178
+ return writeReadableStreamToWritable(nodeResponse.body, res);
179
+
180
+ case 7:
181
+ _context2.next = 10;
182
+ break;
183
+
184
+ case 9:
185
+ res.end();
186
+
187
+ case 10:
188
+ case "end":
189
+ return _context2.stop();
190
+ }
191
+ }
192
+ }, _callee2);
193
+ }));
194
+
195
+ return function sendLoaderResponse(_x2, _x3) {
196
+ return _ref3.apply(this, arguments);
197
+ };
198
+ }();
199
+
200
+ export var getPathWithoutEntry = function getPathWithoutEntry(pathname, entryPath) {
201
+ if (entryPath === '/') {
202
+ return pathname;
203
+ }
204
+
205
+ return pathname.replace(entryPath, '');
206
+ };
207
+
208
+ var matchEntry = function matchEntry(pathname, entries) {
209
+ return entries.find(function (entry) {
210
+ return pathname.startsWith(entry.urlPath);
211
+ });
212
+ };
213
+
214
+ export var handleRequest = /*#__PURE__*/function () {
215
+ var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(_ref4) {
216
+ var context, serverRoutes, distDir, method, query, routeId, entry, _yield$import, routes, res, pathname, matches, match, request, response, message;
217
+
218
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
219
+ while (1) {
220
+ switch (_context3.prev = _context3.next) {
221
+ case 0:
222
+ context = _ref4.context, serverRoutes = _ref4.serverRoutes, distDir = _ref4.distDir;
223
+ method = context.method, query = context.query;
224
+ routeId = query[LOADER_SEARCH_PARAM];
225
+
226
+ if (!(!routeId || method.toLowerCase() !== 'get')) {
227
+ _context3.next = 5;
228
+ break;
229
+ }
230
+
231
+ return _context3.abrupt("return");
232
+
233
+ case 5:
234
+ entry = matchEntry(context.path, serverRoutes);
235
+
236
+ if (entry) {
237
+ _context3.next = 8;
238
+ break;
239
+ }
240
+
241
+ return _context3.abrupt("return");
242
+
243
+ case 8:
244
+ _context3.next = 10;
245
+ return import("".concat(distDir, "/loader-routes/").concat(entry.entryName));
246
+
247
+ case 10:
248
+ _yield$import = _context3.sent;
249
+ routes = _yield$import.routes;
250
+
251
+ if (routes) {
252
+ _context3.next = 14;
253
+ break;
254
+ }
255
+
256
+ return _context3.abrupt("return");
257
+
258
+ case 14:
259
+ res = context.res;
260
+ pathname = getPathWithoutEntry(context.path, entry.urlPath);
261
+ matches = matchRoutes(routes, pathname);
262
+
263
+ if (matches) {
264
+ _context3.next = 21;
265
+ break;
266
+ }
267
+
268
+ res.statusCode = 403;
269
+ res.end("Route ".concat(pathname, " was not matched"));
270
+ return _context3.abrupt("return");
271
+
272
+ case 21:
273
+ match = matches === null || matches === void 0 ? void 0 : matches.find(function (match) {
274
+ return match.route.id === routeId;
275
+ });
276
+
277
+ if (match) {
278
+ _context3.next = 26;
279
+ break;
280
+ }
281
+
282
+ res.statusCode = 403;
283
+ res.end("Route ".concat(routeId, " does not match URL ").concat(context.path));
284
+ return _context3.abrupt("return");
285
+
286
+ case 26:
287
+ request = createLoaderRequest(context);
288
+ _context3.prev = 27;
289
+ _context3.next = 30;
290
+ return callRouteLoader({
291
+ loader: match.route.loader,
292
+ routeId: match.route.id,
293
+ params: match.params,
294
+ request: request,
295
+ loadContext: {}
296
+ });
297
+
298
+ case 30:
299
+ response = _context3.sent;
300
+ _context3.next = 37;
301
+ break;
302
+
303
+ case 33:
304
+ _context3.prev = 33;
305
+ _context3.t0 = _context3["catch"](27);
306
+ message = String(_context3.t0);
307
+ response = new NodeResponse(message, {
308
+ status: 500,
309
+ headers: {
310
+ 'Content-Type': 'text/plain'
311
+ }
312
+ });
313
+
314
+ case 37:
315
+ sendLoaderResponse(res, response);
316
+
317
+ case 38:
318
+ case "end":
319
+ return _context3.stop();
320
+ }
321
+ }
322
+ }, _callee3, null, [[27, 33]]);
323
+ }));
324
+
325
+ return function handleRequest(_x4) {
326
+ return _ref5.apply(this, arguments);
327
+ };
328
+ }();
329
+ export default (function () {
330
+ return {
331
+ name: '@modern-js/plugin-data-loader',
332
+ setup: function setup() {
333
+ return {
334
+ preparebeforeRouteHandler: function preparebeforeRouteHandler(_ref6) {
335
+ var serverRoutes = _ref6.serverRoutes,
336
+ distDir = _ref6.distDir;
337
+ return /*#__PURE__*/function () {
338
+ var _ref7 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(context) {
339
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
340
+ while (1) {
341
+ switch (_context4.prev = _context4.next) {
342
+ case 0:
343
+ return _context4.abrupt("return", handleRequest({
344
+ serverRoutes: serverRoutes,
345
+ distDir: distDir,
346
+ context: context
347
+ }));
348
+
349
+ case 1:
350
+ case "end":
351
+ return _context4.stop();
352
+ }
353
+ }
354
+ }, _callee4);
355
+ }));
356
+
357
+ return function (_x5) {
358
+ return _ref7.apply(this, arguments);
359
+ };
360
+ }();
361
+ }
362
+ };
363
+ }
364
+ };
365
+ });
@@ -0,0 +1,16 @@
1
+ export declare const getRequestUrl: ({
2
+ params,
3
+ request,
4
+ routeId
5
+ }: {
6
+ params: Record<string, string>;
7
+ request: Request;
8
+ routeId: string;
9
+ }) => URL;
10
+ export declare const createRequest: (routeId: string, method?: string) => ({
11
+ params,
12
+ request
13
+ }: {
14
+ params: Record<string, string>;
15
+ request: Request;
16
+ }) => Promise<Response>;
@@ -0,0 +1,7 @@
1
+ export declare const generateClient: ({
2
+ basedir,
3
+ filename
4
+ }: {
5
+ basedir: string;
6
+ filename: string;
7
+ }) => string;
@@ -0,0 +1,4 @@
1
+ import type { LoaderContext } from 'webpack';
2
+ export default function loader(this: LoaderContext<{
3
+ routesDir: string;
4
+ }>, source: string): Promise<string>;
@@ -0,0 +1,20 @@
1
+ import type { ServerPlugin } from '@modern-js/server-core';
2
+ import type { ModernServerContext, ServerRoute } from '@modern-js/types';
3
+ import { Response as NodeResponse } from '@remix-run/node';
4
+ export declare type ServerContext = Pick<ModernServerContext, 'req' | 'res' | 'params' | 'headers' | 'method' | 'url' | 'host' | 'protocol' | 'origin' | 'href' | 'path' | 'query'>;
5
+ export declare function isRedirectResponse(response: NodeResponse): boolean;
6
+ export declare function isResponse(value: any): value is NodeResponse;
7
+ export declare const getPathWithoutEntry: (pathname: string, entryPath: string) => string;
8
+ export declare const handleRequest: ({
9
+ context,
10
+ serverRoutes,
11
+ distDir
12
+ }: {
13
+ context: ServerContext;
14
+ serverRoutes: ServerRoute[];
15
+ distDir: string;
16
+ }) => Promise<void>;
17
+
18
+ declare const _default: () => ServerPlugin;
19
+
20
+ export default _default;
package/package.json ADDED
@@ -0,0 +1,103 @@
1
+ {
2
+ "name": "@modern-js/plugin-data-loader",
3
+ "description": "The meta-framework suite designed from scratch for frontend-focused modern web development.",
4
+ "homepage": "https://modernjs.dev",
5
+ "bugs": "https://github.com/modern-js-dev/modern.js/issues",
6
+ "repository": "modern-js-dev/modern.js",
7
+ "license": "MIT",
8
+ "keywords": [
9
+ "react",
10
+ "framework",
11
+ "modern",
12
+ "modern.js"
13
+ ],
14
+ "version": "0.0.0-next-20221104140607",
15
+ "jsnext:source": "./src/index.ts",
16
+ "types": "./dist/types/index.d.ts",
17
+ "main": "./dist/js/node/index.js",
18
+ "module": "./dist/js/treeshaking/index.js",
19
+ "jsnext:modern": "./dist/js/modern/index.js",
20
+ "exports": {
21
+ "./loader": {
22
+ "jsnext:source": "./src/cli/loader.ts",
23
+ "default": "./dist/js/node/cli/loader.js"
24
+ },
25
+ "./server": {
26
+ "jsnext:source": "./src/server/index.ts",
27
+ "default": "./dist/js/node/server/index.js"
28
+ }
29
+ },
30
+ "typesVersions": {
31
+ "*": {
32
+ "loader": [
33
+ "./dist/types/cli/loader.d.ts"
34
+ ],
35
+ "server": [
36
+ "./dist/types/server/index.d.ts"
37
+ ]
38
+ }
39
+ },
40
+ "dependencies": {
41
+ "@babel/core": "^7.18.0",
42
+ "@babel/runtime": "^7.18.0",
43
+ "@modern-js/babel-compiler": "0.0.0-next-20221104140607",
44
+ "@modern-js/utils": "0.0.0-next-20221104140607",
45
+ "@remix-run/node": "^1.7.0",
46
+ "path-to-regexp": "^6.2.0",
47
+ "react-router-dom": "^6.4.2"
48
+ },
49
+ "devDependencies": {
50
+ "@modern-js/core": "0.0.0-next-20221104140607",
51
+ "@modern-js/runtime": "0.0.0-next-20221104140607",
52
+ "@modern-js/server-core": "0.0.0-next-20221104140607",
53
+ "@modern-js/types": "0.0.0-next-20221104140607",
54
+ "@scripts/build": "0.0.0-next-20221104140607",
55
+ "@scripts/jest-config": "0.0.0-next-20221104140607",
56
+ "@types/babel__core": "^7.1.15",
57
+ "@types/jest": "^27",
58
+ "@types/node": "^14",
59
+ "@types/supertest": "^2.0.11",
60
+ "isomorphic-fetch": "^3.0.0",
61
+ "jest": "^27",
62
+ "memfs": "^3.3.0",
63
+ "supertest": "^6.1.6",
64
+ "ts-jest": "^27.0.5",
65
+ "typescript": "^4",
66
+ "webpack": "^5.74.0",
67
+ "webpack-chain": "^6.5.1"
68
+ },
69
+ "sideEffects": false,
70
+ "publishConfig": {
71
+ "registry": "https://registry.npmjs.org/",
72
+ "access": "public"
73
+ },
74
+ "wireit": {
75
+ "build": {
76
+ "command": "modern build",
77
+ "files": [
78
+ "src/**/*",
79
+ "tsconfig.json",
80
+ "package.json"
81
+ ],
82
+ "output": [
83
+ "dist/**/*"
84
+ ]
85
+ },
86
+ "test": {
87
+ "command": "jest --passWithNoTests",
88
+ "files": [
89
+ "src/**/*",
90
+ "tsconfig.json",
91
+ "package.json",
92
+ "tests/**/*"
93
+ ],
94
+ "output": []
95
+ }
96
+ },
97
+ "scripts": {
98
+ "new": "modern new",
99
+ "build": "wireit",
100
+ "dev": "modern build --watch",
101
+ "test": "wireit"
102
+ }
103
+ }