@shuvi/platform-web 0.0.1-rc.32 → 1.0.0-rc.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/esm/shared/appTypes.d.ts +15 -0
- package/esm/shared/appTypes.js +1 -0
- package/esm/shared/index.d.ts +4 -0
- package/esm/shared/index.js +4 -0
- package/esm/shared/renderTypes.d.ts +44 -0
- package/esm/shared/renderTypes.js +1 -0
- package/esm/shared/routeTypes.d.ts +47 -0
- package/esm/shared/routeTypes.js +1 -0
- package/esm/shared/serverTypes.d.ts +6 -0
- package/esm/shared/serverTypes.js +1 -0
- package/esm/shuvi-app/app/client.d.ts +2 -0
- package/esm/shuvi-app/app/client.js +125 -0
- package/esm/shuvi-app/app/server.d.ts +2 -0
- package/esm/shuvi-app/app/server.js +67 -0
- package/{shuvi-app → esm/shuvi-app}/dev/webpackHotDevClient.d.ts +0 -0
- package/{shuvi-app → esm/shuvi-app}/dev/webpackHotDevClient.js +0 -0
- package/esm/shuvi-app/entry/client/app.d.ts +2 -0
- package/esm/shuvi-app/entry/client/app.js +57 -0
- package/esm/shuvi-app/entry/client/index.d.ts +2 -0
- package/esm/shuvi-app/entry/client/index.js +12 -0
- package/{shuvi-app → esm/shuvi-app}/entry/client/run.dev.d.ts +0 -0
- package/{shuvi-app → esm/shuvi-app}/entry/client/run.dev.js +2 -2
- package/{shuvi-app → esm/shuvi-app}/entry/client/run.prod.d.ts +0 -0
- package/esm/shuvi-app/entry/client/run.prod.js +3 -0
- package/{shuvi-app → esm/shuvi-app}/entry/client/setup-env.d.ts +1 -1
- package/esm/shuvi-app/entry/client/setup-env.js +17 -0
- package/esm/shuvi-app/entry/server/index.d.ts +6 -0
- package/esm/shuvi-app/entry/server/index.js +7 -0
- package/esm/shuvi-app/react/AppComponent.d.ts +4 -0
- package/esm/shuvi-app/react/AppComponent.jsx +6 -0
- package/esm/shuvi-app/react/AppContainer.d.ts +6 -0
- package/esm/shuvi-app/react/AppContainer.jsx +23 -0
- package/esm/shuvi-app/react/Error.d.ts +5 -0
- package/esm/shuvi-app/react/Error.jsx +38 -0
- package/esm/shuvi-app/react/ErrorBoundary.d.ts +16 -0
- package/esm/shuvi-app/react/ErrorBoundary.jsx +25 -0
- package/esm/shuvi-app/react/ErrorPage.d.ts +5 -0
- package/esm/shuvi-app/react/ErrorPage.jsx +7 -0
- package/esm/shuvi-app/react/Link.d.ts +7 -0
- package/esm/shuvi-app/react/Link.jsx +115 -0
- package/esm/shuvi-app/react/applicationContext.d.ts +7 -0
- package/esm/shuvi-app/react/applicationContext.jsx +10 -0
- package/esm/shuvi-app/react/dynamic.d.ts +31 -0
- package/esm/shuvi-app/react/dynamic.jsx +62 -0
- package/esm/shuvi-app/react/getRoutes.d.ts +2 -0
- package/esm/shuvi-app/react/getRoutes.js +31 -0
- package/esm/shuvi-app/react/head/head-manager-context.d.ts +2 -0
- package/esm/shuvi-app/react/head/head-manager-context.js +2 -0
- package/esm/shuvi-app/react/head/head-manager.d.ts +10 -0
- package/esm/shuvi-app/react/head/head-manager.js +93 -0
- package/esm/shuvi-app/react/head/head.d.ts +33 -0
- package/esm/shuvi-app/react/head/head.jsx +178 -0
- package/esm/shuvi-app/react/head/index.d.ts +4 -0
- package/esm/shuvi-app/react/head/index.js +4 -0
- package/esm/shuvi-app/react/head/side-effect.d.ts +30 -0
- package/esm/shuvi-app/react/head/side-effect.jsx +44 -0
- package/esm/shuvi-app/react/head/types.d.ts +15 -0
- package/esm/shuvi-app/react/head/types.js +1 -0
- package/esm/shuvi-app/react/index.d.ts +4 -0
- package/esm/shuvi-app/react/index.js +4 -0
- package/esm/shuvi-app/react/loadRouteComponent.d.ts +4 -0
- package/esm/shuvi-app/react/loadRouteComponent.jsx +9 -0
- package/esm/shuvi-app/react/loadable/index.d.ts +2 -0
- package/esm/shuvi-app/react/loadable/index.js +2 -0
- package/esm/shuvi-app/react/loadable/loadable-context.d.ts +4 -0
- package/esm/shuvi-app/react/loadable/loadable-context.js +3 -0
- package/esm/shuvi-app/react/loadable/loadable.d.ts +30 -0
- package/esm/shuvi-app/react/loadable/loadable.js +277 -0
- package/esm/shuvi-app/react/shuvi-runtime-api.d.ts +5 -0
- package/esm/shuvi-app/react/shuvi-runtime-api.js +5 -0
- package/esm/shuvi-app/react/types.d.ts +14 -0
- package/esm/shuvi-app/react/types.js +1 -0
- package/esm/shuvi-app/react/useLoaderData.d.ts +2 -0
- package/esm/shuvi-app/react/useLoaderData.js +27 -0
- package/esm/shuvi-app/react/utils/getDisplayName.d.ts +2 -0
- package/esm/shuvi-app/react/utils/getDisplayName.js +3 -0
- package/esm/shuvi-app/react/utils/requestIdleCallback.d.ts +2 -0
- package/esm/shuvi-app/react/utils/requestIdleCallback.js +20 -0
- package/esm/shuvi-app/react/utils/useIntersection.d.ts +8 -0
- package/esm/shuvi-app/react/utils/useIntersection.jsx +91 -0
- package/esm/shuvi-app/react/view/ReactView.client.d.ts +5 -0
- package/esm/shuvi-app/react/view/ReactView.client.jsx +64 -0
- package/esm/shuvi-app/react/view/ReactView.server.d.ts +4 -0
- package/esm/shuvi-app/react/view/ReactView.server.jsx +109 -0
- package/esm/shuvi-app/react/view/clientView.d.ts +3 -0
- package/esm/shuvi-app/react/view/clientView.js +2 -0
- package/esm/shuvi-app/react/view/index.d.ts +2 -0
- package/esm/shuvi-app/react/view/index.js +7 -0
- package/esm/shuvi-app/react/view/render-action.d.ts +10 -0
- package/esm/shuvi-app/react/view/render-action.js +29 -0
- package/esm/shuvi-app/react/view/serverView.d.ts +3 -0
- package/esm/shuvi-app/react/view/serverView.js +2 -0
- package/esm/shuvi-app/react/view/transformRoutes.d.ts +2 -0
- package/esm/shuvi-app/react/view/transformRoutes.js +3 -0
- package/esm/shuvi-app/shuvi-runtime-index.d.ts +4 -0
- package/esm/shuvi-app/shuvi-runtime-index.js +2 -0
- package/esm/shuvi-app/shuvi-runtime-server.d.ts +6 -0
- package/esm/shuvi-app/shuvi-runtime-server.js +1 -0
- package/lib/node/features/custom-server/hooks.d.ts +9 -0
- package/lib/node/features/custom-server/hooks.js +13 -0
- package/lib/node/features/custom-server/index.d.ts +17 -0
- package/lib/node/features/custom-server/index.js +28 -0
- package/lib/node/features/custom-server/server.d.ts +2 -0
- package/lib/node/features/custom-server/server.js +32 -0
- package/lib/node/features/custom-server/shuvi-app.d.ts +11 -0
- package/lib/node/features/custom-server/shuvi-app.js +2 -0
- package/lib/node/features/filesystem-routes/api/apiRouteHandler.d.ts +50 -0
- package/lib/node/features/filesystem-routes/api/apiRouteHandler.js +237 -0
- package/lib/node/features/filesystem-routes/api/apiRoutes.d.ts +7 -0
- package/lib/node/features/filesystem-routes/api/apiRoutes.js +35 -0
- package/lib/node/features/filesystem-routes/api/index.d.ts +3 -0
- package/lib/node/features/filesystem-routes/api/index.js +7 -0
- package/lib/node/features/filesystem-routes/api/middleware.d.ts +2 -0
- package/lib/node/features/filesystem-routes/api/middleware.js +46 -0
- package/lib/node/features/filesystem-routes/hooks.d.ts +3 -0
- package/lib/node/features/filesystem-routes/hooks.js +6 -0
- package/lib/node/features/filesystem-routes/index.d.ts +20 -0
- package/lib/node/features/filesystem-routes/index.js +182 -0
- package/lib/node/features/filesystem-routes/middleware/index.d.ts +2 -0
- package/lib/node/features/filesystem-routes/middleware/index.js +7 -0
- package/lib/node/features/filesystem-routes/middleware/middleware.d.ts +2 -0
- package/lib/node/features/filesystem-routes/middleware/middleware.js +42 -0
- package/lib/node/features/filesystem-routes/middleware/routes.d.ts +9 -0
- package/lib/node/features/filesystem-routes/middleware/routes.js +34 -0
- package/lib/node/features/filesystem-routes/page/index.d.ts +2 -0
- package/lib/node/features/filesystem-routes/page/index.js +21 -0
- package/lib/node/features/filesystem-routes/page/routes.d.ts +8 -0
- package/lib/node/features/filesystem-routes/page/routes.js +83 -0
- package/lib/node/features/filesystem-routes/page/store.d.ts +3 -0
- package/lib/node/features/filesystem-routes/page/store.js +10 -0
- package/lib/node/features/filesystem-routes/shuvi-app.d.ts +7 -0
- package/lib/node/features/filesystem-routes/shuvi-app.js +2 -0
- package/lib/node/features/html-render/index.d.ts +16 -0
- package/lib/node/features/html-render/index.js +21 -0
- package/lib/node/features/html-render/lib/generateFilesByRoutId.d.ts +3 -0
- package/lib/node/features/html-render/lib/generateFilesByRoutId.js +13 -0
- package/lib/node/features/html-render/lib/getPageMiddleware.d.ts +2 -0
- package/lib/node/features/html-render/lib/getPageMiddleware.js +56 -0
- package/lib/node/features/html-render/lib/index.d.ts +4 -0
- package/lib/node/features/html-render/lib/index.js +23 -0
- package/lib/node/features/html-render/lib/pageLoader.d.ts +1 -0
- package/lib/node/features/html-render/lib/pageLoader.js +42 -0
- package/lib/node/features/html-render/lib/renderToHTML.d.ts +6 -0
- package/lib/node/features/html-render/lib/renderToHTML.js +81 -0
- package/lib/node/features/html-render/lib/renderer/base.d.ts +17 -0
- package/lib/node/features/html-render/lib/renderer/base.js +70 -0
- package/lib/node/features/html-render/lib/renderer/htmlTag.d.ts +4 -0
- package/lib/node/features/html-render/lib/renderer/htmlTag.js +70 -0
- package/lib/node/features/html-render/lib/renderer/index.d.ts +15 -0
- package/lib/node/features/html-render/lib/renderer/index.js +48 -0
- package/lib/node/features/html-render/lib/renderer/spa.d.ts +5 -0
- package/lib/node/features/html-render/lib/renderer/spa.js +26 -0
- package/lib/node/features/html-render/lib/renderer/ssr.d.ts +5 -0
- package/lib/node/features/html-render/lib/renderer/ssr.js +70 -0
- package/lib/node/features/html-render/lib/renderer/types.d.ts +20 -0
- package/lib/node/features/html-render/lib/renderer/types.js +2 -0
- package/lib/node/features/html-render/lib/viewTemplate.d.ts +5 -0
- package/lib/node/features/html-render/lib/viewTemplate.js +37 -0
- package/lib/node/features/index.d.ts +28 -0
- package/lib/node/features/index.js +25 -0
- package/lib/node/features/main/buildHtml.d.ts +8 -0
- package/lib/node/features/main/buildHtml.js +64 -0
- package/lib/node/features/main/generateResource.d.ts +3 -0
- package/lib/node/features/main/generateResource.js +58 -0
- package/lib/node/features/main/index.d.ts +3 -0
- package/lib/node/features/main/index.js +103 -0
- package/lib/node/features/middlewares.d.ts +4 -0
- package/lib/node/features/middlewares.js +22 -0
- package/lib/node/features/model/index.d.ts +20 -0
- package/lib/node/features/model/index.js +54 -0
- package/lib/node/features/model/runtime.d.ts +8 -0
- package/lib/node/features/model/runtime.js +47 -0
- package/lib/node/features/model/server.d.ts +3 -0
- package/lib/node/features/model/server.js +12 -0
- package/lib/node/features/model/shuvi-app.d.ts +6 -0
- package/lib/node/features/model/shuvi-app.js +2 -0
- package/lib/node/features/on-demand-compile-page/emptyComponent.d.ts +1 -0
- package/lib/node/features/on-demand-compile-page/emptyComponent.js +7 -0
- package/lib/node/features/on-demand-compile-page/index.d.ts +14 -0
- package/lib/node/features/on-demand-compile-page/index.js +36 -0
- package/lib/node/features/on-demand-compile-page/onDemandRouteManager.d.ts +11 -0
- package/lib/node/features/on-demand-compile-page/onDemandRouteManager.js +104 -0
- package/lib/node/index.d.ts +4 -0
- package/lib/node/index.js +39 -0
- package/lib/{paths.d.ts → node/paths.d.ts} +1 -2
- package/lib/node/paths.js +16 -0
- package/lib/node/shuvi-node-extensions.d.ts +17 -0
- package/lib/node/shuvi-node-extensions.js +2 -0
- package/lib/node/targets/react/bundler/index.d.ts +15 -0
- package/lib/node/targets/react/bundler/index.js +102 -0
- package/lib/node/targets/react/index.d.ts +30 -0
- package/lib/node/targets/react/index.js +28 -0
- package/lib/node/targets/react/redox-react/RedoxWrapper.d.ts +8 -0
- package/lib/node/targets/react/redox-react/RedoxWrapper.js +37 -0
- package/lib/node/targets/react/redox-react/index.d.ts +17 -0
- package/lib/node/targets/react/redox-react/index.js +50 -0
- package/lib/node/targets/react/redox-react/runtime.d.ts +2 -0
- package/lib/node/targets/react/redox-react/runtime.js +18 -0
- package/lib/shared/appTypes.d.ts +15 -0
- package/lib/shared/appTypes.js +2 -0
- package/lib/shared/index.d.ts +4 -0
- package/lib/shared/index.js +20 -0
- package/lib/shared/renderTypes.d.ts +44 -0
- package/lib/shared/renderTypes.js +2 -0
- package/lib/shared/routeTypes.d.ts +47 -0
- package/lib/shared/routeTypes.js +2 -0
- package/lib/shared/serverTypes.d.ts +6 -0
- package/lib/shared/serverTypes.js +2 -0
- package/package.json +71 -17
- package/shuvi-app-extensions.d.ts +36 -0
- package/lib/index.d.ts +0 -3
- package/lib/index.js +0 -44
- package/lib/paths.js +0 -7
- package/shuvi-app/application/client/create-application-factory.d.ts +0 -3
- package/shuvi-app/application/client/create-application-factory.js +0 -70
- package/shuvi-app/application/client/create-application-history-browser.d.ts +0 -1
- package/shuvi-app/application/client/create-application-history-browser.js +0 -3
- package/shuvi-app/application/client/create-application-history-hash.d.ts +0 -1
- package/shuvi-app/application/client/create-application-history-hash.js +0 -3
- package/shuvi-app/application/client/create-application-history-memory.d.ts +0 -1
- package/shuvi-app/application/client/create-application-history-memory.js +0 -3
- package/shuvi-app/application/server/create-application-spa.d.ts +0 -2
- package/shuvi-app/application/server/create-application-spa.js +0 -8
- package/shuvi-app/application/server/create-application.d.ts +0 -2
- package/shuvi-app/application/server/create-application.js +0 -25
- package/shuvi-app/entry/client/index.d.ts +0 -1
- package/shuvi-app/entry/client/index.js +0 -11
- package/shuvi-app/entry/client/run.prod.js +0 -3
- package/shuvi-app/entry/client/setup-app.d.ts +0 -3
- package/shuvi-app/entry/client/setup-app.js +0 -38
- package/shuvi-app/entry/client/setup-env.js +0 -27
- package/shuvi-app/entry/server/index.d.ts +0 -6
- package/shuvi-app/entry/server/index.js +0 -7
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import * as React from 'react';
|
|
11
|
+
import { renderToString } from 'react-dom/server';
|
|
12
|
+
import { getLoaderManager, redirect } from '@shuvi/platform-shared/shared';
|
|
13
|
+
import { SHUVI_ERROR } from '@shuvi/shared/lib/constants';
|
|
14
|
+
import { Router } from '@shuvi/router-react';
|
|
15
|
+
import Loadable, { LoadableContext } from '../loadable';
|
|
16
|
+
import AppContainer from '../AppContainer';
|
|
17
|
+
import { Head } from '../head';
|
|
18
|
+
export class ReactServerView {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.renderApp = ({ app, manifest, getAssetPublicUrl }) => __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
yield Loadable.preloadAll();
|
|
22
|
+
const { storeManager, router, error: appError, appComponent: AppComponent } = app;
|
|
23
|
+
yield router.ready;
|
|
24
|
+
// todo: move these into renderer
|
|
25
|
+
let { pathname, matches, redirected } = router.current;
|
|
26
|
+
// handler no matches
|
|
27
|
+
if (!matches.length) {
|
|
28
|
+
appError.error(SHUVI_ERROR.PAGE_NOT_FOUND);
|
|
29
|
+
}
|
|
30
|
+
if (redirected) {
|
|
31
|
+
return redirect(pathname);
|
|
32
|
+
}
|
|
33
|
+
// todo: move loader into app, avoid using global module
|
|
34
|
+
const loaderManager = getLoaderManager();
|
|
35
|
+
const loadersData = yield loaderManager.getAllData();
|
|
36
|
+
const loadableModules = [];
|
|
37
|
+
let htmlContent;
|
|
38
|
+
let head;
|
|
39
|
+
const RootApp = (<Router static router={router}>
|
|
40
|
+
<AppContainer app={app}>
|
|
41
|
+
<LoadableContext.Provider value={moduleName => loadableModules.push(moduleName)}>
|
|
42
|
+
<AppComponent />
|
|
43
|
+
</LoadableContext.Provider>
|
|
44
|
+
</AppContainer>
|
|
45
|
+
</Router>);
|
|
46
|
+
try {
|
|
47
|
+
htmlContent = renderToString(RootApp);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
loaderManager.clearAllData();
|
|
51
|
+
head = Head.rewind() || [];
|
|
52
|
+
}
|
|
53
|
+
const { loadble } = manifest;
|
|
54
|
+
const dynamicImportIdSet = new Set();
|
|
55
|
+
const dynamicImportChunkSet = new Set();
|
|
56
|
+
for (const mod of loadableModules) {
|
|
57
|
+
const manifestItem = loadble[mod];
|
|
58
|
+
if (manifestItem) {
|
|
59
|
+
manifestItem.files.forEach(file => {
|
|
60
|
+
dynamicImportChunkSet.add(file);
|
|
61
|
+
});
|
|
62
|
+
manifestItem.children.forEach(item => {
|
|
63
|
+
dynamicImportIdSet.add(item.id);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const preloadDynamicChunks = [];
|
|
68
|
+
const styles = [];
|
|
69
|
+
for (const file of dynamicImportChunkSet) {
|
|
70
|
+
if (/\.js$/.test(file)) {
|
|
71
|
+
preloadDynamicChunks.push({
|
|
72
|
+
tagName: 'link',
|
|
73
|
+
attrs: {
|
|
74
|
+
rel: 'preload',
|
|
75
|
+
href: getAssetPublicUrl(file),
|
|
76
|
+
as: 'script'
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
else if (/\.css$/.test(file)) {
|
|
81
|
+
styles.push({
|
|
82
|
+
tagName: 'link',
|
|
83
|
+
attrs: {
|
|
84
|
+
rel: 'stylesheet',
|
|
85
|
+
href: getAssetPublicUrl(file)
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const appData = {
|
|
91
|
+
dynamicIds: [...dynamicImportIdSet],
|
|
92
|
+
loadersData
|
|
93
|
+
};
|
|
94
|
+
if (dynamicImportIdSet.size) {
|
|
95
|
+
appData.dynamicIds = Array.from(dynamicImportIdSet);
|
|
96
|
+
}
|
|
97
|
+
appData.appState = storeManager.getState();
|
|
98
|
+
return {
|
|
99
|
+
appData,
|
|
100
|
+
content: htmlContent,
|
|
101
|
+
htmlAttrs: {},
|
|
102
|
+
headBeginTags: [...head, ...preloadDynamicChunks],
|
|
103
|
+
headEndTags: [...styles],
|
|
104
|
+
bodyBeginTags: [],
|
|
105
|
+
bodyEndTags: []
|
|
106
|
+
};
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
declare type RenderActionParam = {
|
|
3
|
+
ssr?: boolean;
|
|
4
|
+
isInitialRender?: boolean;
|
|
5
|
+
root?: ReactNode;
|
|
6
|
+
callback?: () => unknown;
|
|
7
|
+
appContainer?: Element | Document;
|
|
8
|
+
};
|
|
9
|
+
declare let renderAction: (options: RenderActionParam) => void;
|
|
10
|
+
export { renderAction };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
let renderAction;
|
|
2
|
+
if (process.env.__SHUVI__AFTER__REACT__18__) {
|
|
3
|
+
const { createRoot, hydrateRoot } = require('react-dom/client');
|
|
4
|
+
let renderRoot;
|
|
5
|
+
renderAction = ({ ssr, isInitialRender, root, callback, appContainer }) => {
|
|
6
|
+
if (ssr && isInitialRender) {
|
|
7
|
+
renderRoot = hydrateRoot(appContainer, root);
|
|
8
|
+
callback === null || callback === void 0 ? void 0 : callback();
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
if (!renderRoot) {
|
|
12
|
+
renderRoot = createRoot(appContainer);
|
|
13
|
+
}
|
|
14
|
+
renderRoot.render(root);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
const { hydrate, render } = require('react-dom');
|
|
20
|
+
renderAction = ({ ssr, isInitialRender, root, callback, appContainer }) => {
|
|
21
|
+
if (ssr && isInitialRender) {
|
|
22
|
+
hydrate(root, appContainer, callback);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
render(root, appContainer);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export { renderAction };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IServerModule as _IServerModule } from '../shared';
|
|
2
|
+
declare type ServerModule = Required<_IServerModule>;
|
|
3
|
+
export declare type GetPageDataFunction = ServerModule['getPageData'];
|
|
4
|
+
export declare type HandlePageRequestFunction = ServerModule['handlePageRequest'];
|
|
5
|
+
export declare type ModifyHtmlFunction = ServerModule['modifyHtml'];
|
|
6
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
+
import { IAppContext } from '@shuvi/platform-shared/shared';
|
|
3
|
+
import { IHtmlDocument } from '../html-render';
|
|
4
|
+
export declare type IHandlePageRequest = (req: IncomingMessage, res: ServerResponse) => any;
|
|
5
|
+
export declare const extendedHooks: {
|
|
6
|
+
getPageData: import("@shuvi/hook").AsyncParallelHook<void, IAppContext, Record<string, unknown>>;
|
|
7
|
+
handlePageRequest: import("@shuvi/hook").SyncWaterfallHook<IHandlePageRequest, void>;
|
|
8
|
+
modifyHtml: import("@shuvi/hook").AsyncParallelHook<IHtmlDocument, IAppContext, void>;
|
|
9
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extendedHooks = void 0;
|
|
4
|
+
const hook_1 = require("@shuvi/hook");
|
|
5
|
+
const getPageData = (0, hook_1.createAsyncParallelHook)();
|
|
6
|
+
const handlePageRequest = (0, hook_1.createSyncWaterfallHook)();
|
|
7
|
+
// todo: change to AsyncSeries
|
|
8
|
+
const modifyHtml = (0, hook_1.createAsyncParallelHook)();
|
|
9
|
+
exports.extendedHooks = {
|
|
10
|
+
getPageData,
|
|
11
|
+
handlePageRequest,
|
|
12
|
+
modifyHtml
|
|
13
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
core: import("@shuvi/hook").IPluginInstance<{
|
|
3
|
+
afterInit: import("@shuvi/hook").AsyncParallelHook<void, void, void>;
|
|
4
|
+
afterBuild: import("@shuvi/hook").AsyncParallelHook<void, void, void>;
|
|
5
|
+
afterDestroy: import("@shuvi/hook").AsyncParallelHook<void, void, void>;
|
|
6
|
+
afterBundlerDone: import("@shuvi/hook").AsyncParallelHook<import("@shuvi/service/lib/core/lifecycleTypes").BundlerDoneExtra, void, void>;
|
|
7
|
+
afterBundlerTargetDone: import("@shuvi/hook").AsyncParallelHook<import("@shuvi/service/lib/core/lifecycleTypes").BundlerTargetDoneExtra, void, void>;
|
|
8
|
+
configWebpack: import("@shuvi/hook").AsyncSeriesWaterfallHook<import("@shuvi/service/lib/core/lifecycleTypes").WebpackChainType, import("@shuvi/service/lib/core/lifecycleTypes").ConfigWebpackAssistant>;
|
|
9
|
+
addExtraTarget: import("@shuvi/hook").AsyncParallelHook<import("@shuvi/service/lib/core/lifecycleTypes").ExtraTargetAssistant, void, import("@shuvi/service/lib/core/lifecycleTypes").TargetChain>;
|
|
10
|
+
addResource: import("@shuvi/hook").AsyncParallelHook<void, void, import("@shuvi/service/lib/core/lifecycleTypes").Resources | import("@shuvi/service/lib/core/lifecycleTypes").Resources[]>;
|
|
11
|
+
addRuntimeFile: import("@shuvi/hook").AsyncParallelHook<void, import("@shuvi/service/lib/core/lifecycleTypes").AddRuntimeFileUtils, import("@shuvi/service/lib/project/index").FileOptions<any, any> | import("@shuvi/service/lib/project/index").FileOptions<any, any>[]>;
|
|
12
|
+
addRuntimeService: import("@shuvi/hook").AsyncParallelHook<void, void, import("@shuvi/service/lib/core/lifecycleTypes").RuntimeService | import("@shuvi/service/lib/core/lifecycleTypes").RuntimeService[]>;
|
|
13
|
+
} & import("@shuvi/runtime").CustomCorePluginHooks, import("@shuvi/service").IPluginContext>;
|
|
14
|
+
server: import("@shuvi/hook").IPluginInstance<import("@shuvi/service/lib/server/plugin").BuiltInServerPluginHooks & import("@shuvi/runtime").CustomServerPluginHooks, import("@shuvi/service").IServerPluginContext>;
|
|
15
|
+
types: string;
|
|
16
|
+
};
|
|
17
|
+
export default _default;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const service_1 = require("@shuvi/service");
|
|
7
|
+
const file_utils_1 = require("@shuvi/service/lib/project/file-utils");
|
|
8
|
+
const paths_1 = require("../../paths");
|
|
9
|
+
const server_1 = __importDefault(require("./server"));
|
|
10
|
+
const core = (0, service_1.createPlugin)({
|
|
11
|
+
addRuntimeFile: ({ defineFile }, context) => {
|
|
12
|
+
const { paths } = context;
|
|
13
|
+
const serverCandidates = (0, file_utils_1.getUserCustomFileCandidates)(paths.rootDir, 'server', 'noop');
|
|
14
|
+
const userServerFile = defineFile({
|
|
15
|
+
name: 'user/server.js',
|
|
16
|
+
content: () => {
|
|
17
|
+
return (0, file_utils_1.getFirstModuleExport)((0, file_utils_1.getAllFiles)(serverCandidates), serverCandidates);
|
|
18
|
+
},
|
|
19
|
+
dependencies: serverCandidates
|
|
20
|
+
});
|
|
21
|
+
return [userServerFile];
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
exports.default = {
|
|
25
|
+
core,
|
|
26
|
+
server: server_1.default,
|
|
27
|
+
types: (0, paths_1.resolvePkgFile)('lib/node/features/custom-server/shuvi-app.d.ts')
|
|
28
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const service_1 = require("@shuvi/service");
|
|
13
|
+
const resources_1 = require("@shuvi/service/lib/resources");
|
|
14
|
+
const hooks_1 = require("./hooks");
|
|
15
|
+
exports.default = (0, service_1.createServerPlugin)({
|
|
16
|
+
setup: ({ addHooks }) => {
|
|
17
|
+
addHooks(hooks_1.extendedHooks);
|
|
18
|
+
},
|
|
19
|
+
getPageData: (appContext, context) => {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
return ((_b = (_a = resources_1.server === null || resources_1.server === void 0 ? void 0 : resources_1.server.server) === null || _a === void 0 ? void 0 : _a.getPageData) === null || _b === void 0 ? void 0 : _b.call(_a, appContext, context)) || {};
|
|
22
|
+
},
|
|
23
|
+
handlePageRequest: (originalHandlePageRequest, context) => {
|
|
24
|
+
var _a, _b;
|
|
25
|
+
return (((_b = (_a = resources_1.server === null || resources_1.server === void 0 ? void 0 : resources_1.server.server) === null || _a === void 0 ? void 0 : _a.handlePageRequest) === null || _b === void 0 ? void 0 : _b.call(_a, originalHandlePageRequest, context)) ||
|
|
26
|
+
originalHandlePageRequest);
|
|
27
|
+
},
|
|
28
|
+
modifyHtml: (document, context, pluginContext) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
var _a, _b;
|
|
30
|
+
yield ((_b = (_a = resources_1.server === null || resources_1.server === void 0 ? void 0 : resources_1.server.server) === null || _a === void 0 ? void 0 : _a.modifyHtml) === null || _b === void 0 ? void 0 : _b.call(_a, document, context, pluginContext));
|
|
31
|
+
})
|
|
32
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { extendedHooks } from './hooks';
|
|
2
|
+
declare module '@shuvi/runtime' {
|
|
3
|
+
interface CustomAppContext {
|
|
4
|
+
pageData?: any;
|
|
5
|
+
}
|
|
6
|
+
interface CustomServerPluginHooks {
|
|
7
|
+
getPageData: typeof extendedHooks.getPageData;
|
|
8
|
+
handlePageRequest: typeof extendedHooks.handlePageRequest;
|
|
9
|
+
modifyHtml: typeof extendedHooks.modifyHtml;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { IncomingMessage } from 'http';
|
|
2
|
+
import { IResponse, IRequest } from '@shuvi/service';
|
|
3
|
+
import { IApiRequestHandler, IApiResponse } from '../../../../shared';
|
|
4
|
+
export { IApiRequestHandler };
|
|
5
|
+
export declare function apiRouteHandler(req: IRequest, res: IResponse, resolver: IApiRequestHandler, apiRoutesConfig: any): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Parse incoming message like `json` or `urlencoded`
|
|
8
|
+
* @param req request object
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseBody(req: IRequest, limit: string | number): Promise<any>;
|
|
11
|
+
/**
|
|
12
|
+
* Parse cookies from `req` header
|
|
13
|
+
* @param req request object
|
|
14
|
+
*/
|
|
15
|
+
export declare function getCookieParser(req: IncomingMessage): {
|
|
16
|
+
[key: string]: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param res ServerResponse object
|
|
21
|
+
* @param statusCode `HTTP` status code of response
|
|
22
|
+
*/
|
|
23
|
+
export declare function sendStatusCode<IRes extends IApiResponse>(res: IResponse, statusCode: number): IRes;
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param res response object
|
|
27
|
+
* @param [statusOrUrl] `HTTP` status code of redirect
|
|
28
|
+
* @param url URL of redirect
|
|
29
|
+
*/
|
|
30
|
+
export declare function redirect<IRes extends IApiResponse>(res: IResponse, statusOrUrl: string | number, url?: string): IRes;
|
|
31
|
+
/**
|
|
32
|
+
* Send `any` body to response
|
|
33
|
+
* @param req request object
|
|
34
|
+
* @param res response object
|
|
35
|
+
* @param body of response
|
|
36
|
+
*/
|
|
37
|
+
export declare function sendData(req: IRequest, res: IResponse, body: any): void;
|
|
38
|
+
/**
|
|
39
|
+
* Send `JSON` object
|
|
40
|
+
* @param res response object
|
|
41
|
+
* @param jsonBody of data
|
|
42
|
+
*/
|
|
43
|
+
export declare function sendJson(req: IRequest, res: IResponse, jsonBody: any): void;
|
|
44
|
+
/**
|
|
45
|
+
* Custom error class
|
|
46
|
+
*/
|
|
47
|
+
export declare class ApiError extends Error {
|
|
48
|
+
readonly statusCode: number;
|
|
49
|
+
constructor(statusCode: number, message: string);
|
|
50
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
|
+
exports.ApiError = exports.sendJson = exports.sendData = exports.redirect = exports.sendStatusCode = exports.getCookieParser = exports.parseBody = exports.apiRouteHandler = void 0;
|
|
36
|
+
const stream_1 = require("stream");
|
|
37
|
+
const querystring = __importStar(require("querystring"));
|
|
38
|
+
const cookie = __importStar(require("cookie"));
|
|
39
|
+
const getRawBody = require('raw-body');
|
|
40
|
+
const contentType = __importStar(require("content-type"));
|
|
41
|
+
function apiRouteHandler(req, res, resolver, apiRoutesConfig) {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
try {
|
|
44
|
+
const { bodyParser } = apiRoutesConfig || {};
|
|
45
|
+
const { pathname, query, params } = req;
|
|
46
|
+
const apiReq = {
|
|
47
|
+
pathname,
|
|
48
|
+
query,
|
|
49
|
+
params,
|
|
50
|
+
// Parsing of cookies
|
|
51
|
+
cookies: getCookieParser(req)
|
|
52
|
+
};
|
|
53
|
+
// Parsing of body
|
|
54
|
+
if (bodyParser && !apiReq.body) {
|
|
55
|
+
apiReq.body = yield parseBody(req, bodyParser && bodyParser.sizeLimit ? bodyParser.sizeLimit : '1mb');
|
|
56
|
+
}
|
|
57
|
+
const apiRes = {
|
|
58
|
+
status: (statusCode) => sendStatusCode(res, statusCode),
|
|
59
|
+
send: (data) => sendData(req, res, data),
|
|
60
|
+
json: (data) => sendJson(req, res, data),
|
|
61
|
+
redirect: (statusOrUrl, url) => redirect(res, statusOrUrl, url)
|
|
62
|
+
};
|
|
63
|
+
let wasPiped = false;
|
|
64
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
65
|
+
// listen for pipe event and don't show resolve warning
|
|
66
|
+
res.once('pipe', () => (wasPiped = true));
|
|
67
|
+
}
|
|
68
|
+
// Call API route method
|
|
69
|
+
yield resolver(Object.assign(req, apiReq), Object.assign(res, apiRes));
|
|
70
|
+
if (process.env.NODE_ENV !== 'production' &&
|
|
71
|
+
!(res.finished || res.headersSent) &&
|
|
72
|
+
!wasPiped) {
|
|
73
|
+
console.warn(`API resolved without sending a response for ${req.url}, this may result in stalled requests.`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
exports.apiRouteHandler = apiRouteHandler;
|
|
82
|
+
/**
|
|
83
|
+
* Parse incoming message like `json` or `urlencoded`
|
|
84
|
+
* @param req request object
|
|
85
|
+
*/
|
|
86
|
+
function parseBody(req, limit) {
|
|
87
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
let contentTypeObj;
|
|
89
|
+
try {
|
|
90
|
+
contentTypeObj = contentType.parse(req.headers['content-type'] || 'text/plain');
|
|
91
|
+
}
|
|
92
|
+
catch (_a) {
|
|
93
|
+
contentTypeObj = contentType.parse('text/plain');
|
|
94
|
+
}
|
|
95
|
+
const { type, parameters } = contentTypeObj;
|
|
96
|
+
const encoding = (parameters.charset && parameters.charset.toLowerCase()) || 'utf-8';
|
|
97
|
+
let buffer;
|
|
98
|
+
try {
|
|
99
|
+
buffer = yield getRawBody(req, { encoding, limit });
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
if (e.type === 'entity.too.large') {
|
|
103
|
+
throw new ApiError(413, `Body exceeded ${limit} limit`);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
throw new ApiError(400, 'Invalid body');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const body = buffer.toString();
|
|
110
|
+
if (type === 'application/json' || type === 'application/ld+json') {
|
|
111
|
+
return parseJson(body);
|
|
112
|
+
}
|
|
113
|
+
else if (type === 'application/x-www-form-urlencoded') {
|
|
114
|
+
return querystring.decode(body);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
return body;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
exports.parseBody = parseBody;
|
|
122
|
+
/**
|
|
123
|
+
* Parse `JSON` and handles invalid `JSON` strings
|
|
124
|
+
* @param str `JSON` string
|
|
125
|
+
*/
|
|
126
|
+
function parseJson(str) {
|
|
127
|
+
if (str.length === 0) {
|
|
128
|
+
// special-case empty json body, as it's a common client-side mistake
|
|
129
|
+
return {};
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
return JSON.parse(str);
|
|
133
|
+
}
|
|
134
|
+
catch (e) {
|
|
135
|
+
throw new ApiError(400, 'Invalid JSON');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Parse cookies from `req` header
|
|
140
|
+
* @param req request object
|
|
141
|
+
*/
|
|
142
|
+
function getCookieParser(req) {
|
|
143
|
+
const header = req.headers.cookie;
|
|
144
|
+
if (!header) {
|
|
145
|
+
return {};
|
|
146
|
+
}
|
|
147
|
+
return cookie.parse(Array.isArray(header) ? header.join(';') : header);
|
|
148
|
+
}
|
|
149
|
+
exports.getCookieParser = getCookieParser;
|
|
150
|
+
/**
|
|
151
|
+
*
|
|
152
|
+
* @param res ServerResponse object
|
|
153
|
+
* @param statusCode `HTTP` status code of response
|
|
154
|
+
*/
|
|
155
|
+
function sendStatusCode(res, statusCode) {
|
|
156
|
+
res.statusCode = statusCode;
|
|
157
|
+
return res;
|
|
158
|
+
}
|
|
159
|
+
exports.sendStatusCode = sendStatusCode;
|
|
160
|
+
/**
|
|
161
|
+
*
|
|
162
|
+
* @param res response object
|
|
163
|
+
* @param [statusOrUrl] `HTTP` status code of redirect
|
|
164
|
+
* @param url URL of redirect
|
|
165
|
+
*/
|
|
166
|
+
function redirect(res, statusOrUrl, url) {
|
|
167
|
+
if (typeof statusOrUrl === 'string') {
|
|
168
|
+
url = statusOrUrl;
|
|
169
|
+
statusOrUrl = 307;
|
|
170
|
+
}
|
|
171
|
+
if (typeof statusOrUrl !== 'number' || typeof url !== 'string') {
|
|
172
|
+
throw new Error(`Invalid redirect arguments. Please use a single argument URL, e.g. res.redirect('/destination') or use a status code and URL, e.g. res.redirect(307, '/destination').`);
|
|
173
|
+
}
|
|
174
|
+
res.writeHead(statusOrUrl, { Location: url });
|
|
175
|
+
res.write('');
|
|
176
|
+
res.end();
|
|
177
|
+
return res;
|
|
178
|
+
}
|
|
179
|
+
exports.redirect = redirect;
|
|
180
|
+
/**
|
|
181
|
+
* Send `any` body to response
|
|
182
|
+
* @param req request object
|
|
183
|
+
* @param res response object
|
|
184
|
+
* @param body of response
|
|
185
|
+
*/
|
|
186
|
+
function sendData(req, res, body) {
|
|
187
|
+
if (body === null || body === undefined) {
|
|
188
|
+
res.end();
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const contentType = res.getHeader('Content-Type');
|
|
192
|
+
if (body instanceof stream_1.Stream) {
|
|
193
|
+
if (!contentType) {
|
|
194
|
+
res.setHeader('Content-Type', 'application/octet-stream');
|
|
195
|
+
}
|
|
196
|
+
body.pipe(res);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
const isJSONLike = ['object', 'number', 'boolean'].includes(typeof body);
|
|
200
|
+
const stringifiedBody = isJSONLike ? JSON.stringify(body) : body;
|
|
201
|
+
if (Buffer.isBuffer(body)) {
|
|
202
|
+
if (!contentType) {
|
|
203
|
+
res.setHeader('Content-Type', 'application/octet-stream');
|
|
204
|
+
}
|
|
205
|
+
res.setHeader('Content-Length', body.length);
|
|
206
|
+
res.end(body);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
if (isJSONLike) {
|
|
210
|
+
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
211
|
+
}
|
|
212
|
+
res.setHeader('Content-Length', Buffer.byteLength(stringifiedBody));
|
|
213
|
+
res.end(stringifiedBody);
|
|
214
|
+
}
|
|
215
|
+
exports.sendData = sendData;
|
|
216
|
+
/**
|
|
217
|
+
* Send `JSON` object
|
|
218
|
+
* @param res response object
|
|
219
|
+
* @param jsonBody of data
|
|
220
|
+
*/
|
|
221
|
+
function sendJson(req, res, jsonBody) {
|
|
222
|
+
// Set header to application/json
|
|
223
|
+
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
224
|
+
// Use send to handle request
|
|
225
|
+
return sendData(req, res, jsonBody);
|
|
226
|
+
}
|
|
227
|
+
exports.sendJson = sendJson;
|
|
228
|
+
/**
|
|
229
|
+
* Custom error class
|
|
230
|
+
*/
|
|
231
|
+
class ApiError extends Error {
|
|
232
|
+
constructor(statusCode, message) {
|
|
233
|
+
super(message);
|
|
234
|
+
this.statusCode = statusCode;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
exports.ApiError = ApiError;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { IApiRouteConfig } from '@shuvi/platform-shared/node';
|
|
2
|
+
export { IApiRouteConfig };
|
|
3
|
+
export declare function serializeApiRoutes(apiRoutes: IApiRouteConfig[]): string;
|
|
4
|
+
export declare function normalizeApiRoutes(apiRoutes: IApiRouteConfig[], option: {
|
|
5
|
+
apisDir: string;
|
|
6
|
+
}): IApiRouteConfig[];
|
|
7
|
+
export declare const generateRoutesContent: (apiRoutes: IApiRouteConfig[], apisDir: string) => string;
|