@rsdoctor/core 2.0.0-alpha.1 → 2.0.0-alpha.2
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/26.js +26163 -0
- package/dist/630.js +1269 -0
- package/dist/630.js.LICENSE.txt +7 -0
- package/dist/build-utils/build/chunks/assetsModules.d.ts +7 -1
- package/dist/build-utils/build/loader/probeLoader.d.ts +7 -2
- package/dist/build-utils/build/utils/parseBundle.d.ts +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +1725 -7
- package/dist/inner-plugins/constants.d.ts +1 -1
- package/dist/inner-plugins/plugins/base.d.ts +2 -2
- package/dist/logger.d.ts +2 -2
- package/dist/probe-loader.js +2 -0
- package/dist/proxy-loader.d.ts +1 -0
- package/dist/proxy-loader.js +48 -0
- package/dist/rslib-runtime.js +28 -0
- package/dist/rspack-plugin/constants.d.ts +1 -1
- package/dist/rules/rules/ecma-version-check/htmlParserStub.d.ts +3 -0
- package/dist/rules/rules/ecma-version-check/types.d.ts +13 -2
- package/dist/sdk/server/apis/base.d.ts +1 -1
- package/dist/sdk/server/socket/api.d.ts +1 -1
- package/dist/sdk/utils/date.d.ts +1 -0
- package/dist/types/loader.d.ts +1 -1
- package/package.json +20 -113
- package/dist/build-utils/build/chunks/assetsModules.js +0 -9
- package/dist/build-utils/build/chunks/index.js +0 -3
- package/dist/build-utils/build/chunks/rspack/transform.js +0 -44
- package/dist/build-utils/build/envinfo.js +0 -60
- package/dist/build-utils/build/file/cache.js +0 -24
- package/dist/build-utils/build/file/index.js +0 -5
- package/dist/build-utils/build/file/sharding.js +0 -38
- package/dist/build-utils/build/index.js +0 -12
- package/dist/build-utils/build/json.js +0 -67
- package/dist/build-utils/build/loader/index.js +0 -3
- package/dist/build-utils/build/loader/probeLoader.js +0 -44
- package/dist/build-utils/build/loader/probeLoaderPlugin.js +0 -32
- package/dist/build-utils/build/module-graph/index.js +0 -2
- package/dist/build-utils/build/module-graph/parser.js +0 -13
- package/dist/build-utils/build/module-graph/rspack/transform.js +0 -111
- package/dist/build-utils/build/module-graph/utils.js +0 -60
- package/dist/build-utils/build/process.js +0 -18
- package/dist/build-utils/build/server.js +0 -107
- package/dist/build-utils/build/utils/index.js +0 -4
- package/dist/build-utils/build/utils/loader.js +0 -267
- package/dist/build-utils/build/utils/parseBundle.js +0 -238
- package/dist/build-utils/build/utils/plugin.js +0 -21
- package/dist/build-utils/index.js +0 -13
- package/dist/collection.d.ts +0 -1
- package/dist/collection.js +0 -2
- package/dist/common/file.js +0 -8
- package/dist/common/global-config.js +0 -33
- package/dist/common/index.d.ts +0 -4
- package/dist/common/index.js +0 -6
- package/dist/common-browser.d.ts +0 -1
- package/dist/common-browser.js +0 -2
- package/dist/error/error.js +0 -143
- package/dist/error/index.js +0 -3
- package/dist/error/transform.js +0 -138
- package/dist/error/utils.js +0 -23
- package/dist/graph/index.d.ts +0 -1
- package/dist/graph/index.js +0 -2
- package/dist/inner-plugins/constants.js +0 -19
- package/dist/inner-plugins/index.js +0 -3
- package/dist/inner-plugins/loaders/proxy.js +0 -65
- package/dist/inner-plugins/plugins/base.js +0 -20
- package/dist/inner-plugins/plugins/bundle.js +0 -63
- package/dist/inner-plugins/plugins/ensureModulesChunkGraph.js +0 -74
- package/dist/inner-plugins/plugins/errors.js +0 -65
- package/dist/inner-plugins/plugins/index.js +0 -11
- package/dist/inner-plugins/plugins/loader.js +0 -108
- package/dist/inner-plugins/plugins/plugins.js +0 -40
- package/dist/inner-plugins/plugins/progress.js +0 -35
- package/dist/inner-plugins/plugins/resolver.js +0 -57
- package/dist/inner-plugins/plugins/rspack.js +0 -99
- package/dist/inner-plugins/plugins/rules.js +0 -64
- package/dist/inner-plugins/plugins/sourcemapTool.js +0 -230
- package/dist/inner-plugins/plugins/summary.js +0 -92
- package/dist/inner-plugins/utils/circleDetect.js +0 -16
- package/dist/inner-plugins/utils/config.js +0 -141
- package/dist/inner-plugins/utils/index.js +0 -8
- package/dist/inner-plugins/utils/loader.js +0 -134
- package/dist/inner-plugins/utils/normalize-config.js +0 -77
- package/dist/inner-plugins/utils/openBrowser.js +0 -55
- package/dist/inner-plugins/utils/plugin-common.js +0 -94
- package/dist/inner-plugins/utils/plugin.js +0 -70
- package/dist/inner-plugins/utils/sdk.js +0 -19
- package/dist/logger.js +0 -51
- package/dist/rspack-plugin/constants.js +0 -23
- package/dist/rspack-plugin/index.js +0 -3
- package/dist/rspack-plugin/multiple.js +0 -39
- package/dist/rspack-plugin/plugin.js +0 -133
- package/dist/rule-utils/document/document.js +0 -46
- package/dist/rule-utils/document/index.js +0 -4
- package/dist/rule-utils/document/server.js +0 -13
- package/dist/rule-utils/document/types.js +0 -1
- package/dist/rule-utils/index.js +0 -3
- package/dist/rule-utils/parser/asserts.js +0 -105
- package/dist/rule-utils/parser/index.js +0 -5
- package/dist/rule-utils/parser/parser.js +0 -24
- package/dist/rule-utils/parser/types.js +0 -8
- package/dist/rule-utils/parser/utils.js +0 -106
- package/dist/rules/index.js +0 -4
- package/dist/rules/linter.js +0 -36
- package/dist/rules/rule.js +0 -101
- package/dist/rules/rules/cjs-require/index.js +0 -50
- package/dist/rules/rules/cjs-require/types.js +0 -1
- package/dist/rules/rules/cross-chunks-package/index.js +0 -41
- package/dist/rules/rules/cross-chunks-package/types.js +0 -1
- package/dist/rules/rules/cross-chunks-package/utils.js +0 -7
- package/dist/rules/rules/default-import-check/index.js +0 -83
- package/dist/rules/rules/default-import-check/types.js +0 -1
- package/dist/rules/rules/default-import-check/utils.js +0 -52
- package/dist/rules/rules/duplicate-package/index.js +0 -39
- package/dist/rules/rules/duplicate-package/types.js +0 -24
- package/dist/rules/rules/duplicate-package/utils.js +0 -38
- package/dist/rules/rules/ecma-version-check/index.js +0 -53
- package/dist/rules/rules/ecma-version-check/types.js +0 -1
- package/dist/rules/rules/ecma-version-check/utils.js +0 -6
- package/dist/rules/rules/esm-resolved-to-cjs/index.js +0 -193
- package/dist/rules/rules/esm-resolved-to-cjs/types.js +0 -1
- package/dist/rules/rules/index.js +0 -22
- package/dist/rules/rules/loader-performance-optimization/index.js +0 -86
- package/dist/rules/rules/loader-performance-optimization/types.js +0 -1
- package/dist/rules/rules/loader-performance-optimization/utils.js +0 -10
- package/dist/rules/rules/module-mixed-chunks/index.js +0 -52
- package/dist/rules/rules/module-mixed-chunks/types.js +0 -1
- package/dist/rules/rules/side-effects-only-imports/index.js +0 -81
- package/dist/rules/rules/side-effects-only-imports/types.js +0 -1
- package/dist/rules/utils.js +0 -10
- package/dist/sdk/index.js +0 -3
- package/dist/sdk/multiple/controller.js +0 -42
- package/dist/sdk/multiple/index.js +0 -3
- package/dist/sdk/multiple/primary.js +0 -64
- package/dist/sdk/multiple/server.js +0 -14
- package/dist/sdk/sdk/core.js +0 -163
- package/dist/sdk/sdk/index.js +0 -435
- package/dist/sdk/sdk/types.js +0 -1
- package/dist/sdk/server/apis/alerts.js +0 -30
- package/dist/sdk/server/apis/base.js +0 -22
- package/dist/sdk/server/apis/bundle-diff.js +0 -51
- package/dist/sdk/server/apis/data.js +0 -44
- package/dist/sdk/server/apis/fs.js +0 -28
- package/dist/sdk/server/apis/graph.js +0 -116
- package/dist/sdk/server/apis/index.js +0 -11
- package/dist/sdk/server/apis/loader.js +0 -120
- package/dist/sdk/server/apis/plugin.js +0 -39
- package/dist/sdk/server/apis/project.js +0 -59
- package/dist/sdk/server/apis/renderer.js +0 -33
- package/dist/sdk/server/apis/resolver.js +0 -38
- package/dist/sdk/server/client.js +0 -8
- package/dist/sdk/server/fakeServer.js +0 -12
- package/dist/sdk/server/index.js +0 -292
- package/dist/sdk/server/json-body.js +0 -150
- package/dist/sdk/server/router.js +0 -83
- package/dist/sdk/server/security.js +0 -47
- package/dist/sdk/server/socket/api.js +0 -22
- package/dist/sdk/server/socket/index.js +0 -166
- package/dist/sdk/server/utils.js +0 -19
- package/dist/sdk/utils/base.js +0 -22
- package/dist/sdk/utils/constant.js +0 -4
- package/dist/sdk/utils/index.js +0 -4
- package/dist/sdk/utils/openBrowser.js +0 -53
- package/dist/sdk/utils/upload.js +0 -6
- package/dist/sdk.js +0 -2
- package/dist/types/index.js +0 -4
- package/dist/types/loader.js +0 -1
- package/dist/types/plugin.js +0 -1
- package/dist/types/rules.js +0 -1
package/dist/sdk/server/index.js
DELETED
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
import "node:module";
|
|
2
|
-
import { Client, SDK } from "@rsdoctor/shared/types";
|
|
3
|
-
import { Server } from "../../build-utils/index.js";
|
|
4
|
-
import sirv from "sirv";
|
|
5
|
-
import { Bundle, GlobalConfig } from "../../common/index.js";
|
|
6
|
-
import assert from "assert";
|
|
7
|
-
import cors from "cors";
|
|
8
|
-
import { PassThrough } from "stream";
|
|
9
|
-
import { Socket } from "./socket/index.js";
|
|
10
|
-
import { Router } from "./router.js";
|
|
11
|
-
import * as __rspack_external__apis_index_js_275823d6 from "./apis/index.js";
|
|
12
|
-
import { chalk, logger } from "../../logger.js";
|
|
13
|
-
import { openBrowser } from "../utils/openBrowser.js";
|
|
14
|
-
import path from "path";
|
|
15
|
-
import { createRequire } from "module";
|
|
16
|
-
import { randomBytes } from "crypto";
|
|
17
|
-
import { jsonBodyParser } from "./json-body.js";
|
|
18
|
-
import { DEFAULT_ALLOWED_CORS_ORIGINS, isAllowedCorsRequest, isAllowedOpenInEditorToken, isAllowedRequestHost } from "./security.js";
|
|
19
|
-
export * from "./utils.js";
|
|
20
|
-
const server_require = createRequire(import.meta.url);
|
|
21
|
-
const OPEN_IN_EDITOR_PATH = '/__open-in-editor';
|
|
22
|
-
const LISTEN_RETRY_LIMIT = 10;
|
|
23
|
-
const OPEN_IN_EDITOR_EDITORS = new Set(SDK.OPEN_IN_EDITOR_EDITORS);
|
|
24
|
-
const DEFAULT_JSON_BODY_LIMIT = '10mb';
|
|
25
|
-
const LARGE_JSON_BODY_LIMIT = '500mb';
|
|
26
|
-
const LARGE_JSON_BODY_ROUTES = new Set([
|
|
27
|
-
SDK.ServerAPI.API.ReportLoader,
|
|
28
|
-
SDK.ServerAPI.API.ReportSourceMap
|
|
29
|
-
]);
|
|
30
|
-
function isAddressInUseError(error) {
|
|
31
|
-
return 'EADDRINUSE' === error.code;
|
|
32
|
-
}
|
|
33
|
-
function isAllowedOpenInEditorEditor(editor) {
|
|
34
|
-
return 'string' == typeof editor && OPEN_IN_EDITOR_EDITORS.has(editor);
|
|
35
|
-
}
|
|
36
|
-
class RsdoctorServer {
|
|
37
|
-
get app() {
|
|
38
|
-
return this._server.app;
|
|
39
|
-
}
|
|
40
|
-
get host() {
|
|
41
|
-
return Server.defaultHost;
|
|
42
|
-
}
|
|
43
|
-
get origin() {
|
|
44
|
-
return `http://${this.host}:${this.port}`;
|
|
45
|
-
}
|
|
46
|
-
get socketUrl() {
|
|
47
|
-
return {
|
|
48
|
-
port: this.port,
|
|
49
|
-
socketUrl: `ws://localhost:${this.port}?token=${this._socketToken}`,
|
|
50
|
-
token: this._socketToken
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
get innerClientPath() {
|
|
54
|
-
return this._innerClientPath;
|
|
55
|
-
}
|
|
56
|
-
async createInnerServer() {
|
|
57
|
-
let expectedPort = this.port;
|
|
58
|
-
let lastError;
|
|
59
|
-
for(let retry = 0; retry < LISTEN_RETRY_LIMIT; retry++){
|
|
60
|
-
const port = Server.getPortSync(expectedPort, this.host);
|
|
61
|
-
try {
|
|
62
|
-
return {
|
|
63
|
-
port,
|
|
64
|
-
server: await Server.createServer(port, this.host)
|
|
65
|
-
};
|
|
66
|
-
} catch (error) {
|
|
67
|
-
if (!isAddressInUseError(error)) throw error;
|
|
68
|
-
lastError = error;
|
|
69
|
-
expectedPort = port + 1;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
throw lastError;
|
|
73
|
-
}
|
|
74
|
-
resolveCorsOptions() {
|
|
75
|
-
if (false === this._cors) return false;
|
|
76
|
-
if (true === this._cors) return {};
|
|
77
|
-
if (void 0 === this._cors) return {
|
|
78
|
-
origin: DEFAULT_ALLOWED_CORS_ORIGINS
|
|
79
|
-
};
|
|
80
|
-
return {
|
|
81
|
-
...this._cors,
|
|
82
|
-
origin: void 0 === this._cors.origin ? DEFAULT_ALLOWED_CORS_ORIGINS : this._cors.origin
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
async bootstrap() {
|
|
86
|
-
if (!this.disposed) return;
|
|
87
|
-
const { port, server } = await this.createInnerServer();
|
|
88
|
-
const corsOptions = this.resolveCorsOptions();
|
|
89
|
-
this.port = port;
|
|
90
|
-
this._server = server;
|
|
91
|
-
this._socket = new Socket({
|
|
92
|
-
sdk: this.sdk,
|
|
93
|
-
server: this._server.server,
|
|
94
|
-
port: this.port,
|
|
95
|
-
token: this._socketToken
|
|
96
|
-
});
|
|
97
|
-
await this._socket.bootstrap();
|
|
98
|
-
GlobalConfig.writeMcpPort(this.port, this.sdk.name);
|
|
99
|
-
logger.debug(`Successfully wrote mcp.json for ${chalk.cyan(this.sdk.name)} builder`);
|
|
100
|
-
this.disposed = false;
|
|
101
|
-
this.app.use((req, res, next)=>{
|
|
102
|
-
const host = req.headers.host || req.headers[':authority'];
|
|
103
|
-
if (!isAllowedRequestHost(host)) {
|
|
104
|
-
res.statusCode = 403;
|
|
105
|
-
res.end();
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
next();
|
|
109
|
-
});
|
|
110
|
-
if (false !== corsOptions && corsOptions.origin === DEFAULT_ALLOWED_CORS_ORIGINS) this.app.use((req, res, next)=>{
|
|
111
|
-
const host = req.headers.host || req.headers[':authority'];
|
|
112
|
-
if (!isAllowedCorsRequest(req.headers.origin, host)) {
|
|
113
|
-
res.statusCode = 403;
|
|
114
|
-
res.end();
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
next();
|
|
118
|
-
});
|
|
119
|
-
if (false !== corsOptions) this.app.use(cors(corsOptions));
|
|
120
|
-
this.app.use(jsonBodyParser({
|
|
121
|
-
limit: (req)=>{
|
|
122
|
-
const pathname = new URL(req.url || '/', 'http://localhost').pathname;
|
|
123
|
-
return LARGE_JSON_BODY_ROUTES.has(pathname) ? LARGE_JSON_BODY_LIMIT : DEFAULT_JSON_BODY_LIMIT;
|
|
124
|
-
}
|
|
125
|
-
}));
|
|
126
|
-
await this._router.setup();
|
|
127
|
-
const clientHtmlPath = this._innerClientPath ? this._innerClientPath : server_require.resolve('@rsdoctor/client');
|
|
128
|
-
const clientDistPath = path.resolve(clientHtmlPath, '..');
|
|
129
|
-
this.app.use(sirv(clientDistPath, {
|
|
130
|
-
dev: true
|
|
131
|
-
}));
|
|
132
|
-
this.app.use(OPEN_IN_EDITOR_PATH, (req, res, next)=>{
|
|
133
|
-
if ('GET' !== req.method && 'HEAD' !== req.method) return next();
|
|
134
|
-
const url = new URL(req.url || '', "http://localhost");
|
|
135
|
-
const file = url.searchParams.get('file');
|
|
136
|
-
const editor = url.searchParams.get('editor');
|
|
137
|
-
const token = url.searchParams.get('token');
|
|
138
|
-
if (!isAllowedOpenInEditorToken(token, this._socketToken)) {
|
|
139
|
-
res.statusCode = 403;
|
|
140
|
-
res.end();
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
if (!file) {
|
|
144
|
-
res.statusCode = 400;
|
|
145
|
-
res.end('Missing file parameter');
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
if (!isAllowedOpenInEditorEditor(editor)) {
|
|
149
|
-
res.statusCode = 400;
|
|
150
|
-
res.end('Unsupported editor parameter');
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
try {
|
|
154
|
-
const launch = server_require('launch-editor');
|
|
155
|
-
let responded = false;
|
|
156
|
-
const safeEnd = (code, body)=>{
|
|
157
|
-
if (responded) return;
|
|
158
|
-
responded = true;
|
|
159
|
-
res.statusCode = code;
|
|
160
|
-
res.end(body);
|
|
161
|
-
};
|
|
162
|
-
launch(file, editor, (_fileName, errorMessage)=>{
|
|
163
|
-
if (errorMessage) safeEnd(500, errorMessage);
|
|
164
|
-
});
|
|
165
|
-
setTimeout(()=>{
|
|
166
|
-
safeEnd(200, '');
|
|
167
|
-
}, 200);
|
|
168
|
-
} catch (err) {
|
|
169
|
-
if (!res.writableEnded) {
|
|
170
|
-
res.statusCode = 500;
|
|
171
|
-
res.end(err.message);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
process.once('exit', ()=>this.dispose());
|
|
176
|
-
process.once('SIGINT', ()=>this.dispose(0));
|
|
177
|
-
process.once('SIGTERM', ()=>this.dispose(0));
|
|
178
|
-
process.once('unhandledRejection', (reason)=>{
|
|
179
|
-
console.error('Unhandled promise rejection:', reason);
|
|
180
|
-
this.dispose(1);
|
|
181
|
-
});
|
|
182
|
-
process.once('uncaughtException', (err, origin)=>{
|
|
183
|
-
console.error('Uncaught exception:', err);
|
|
184
|
-
if (origin) console.error('Exception origin:', origin);
|
|
185
|
-
this.dispose(1);
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
wrapNextHandleFunction(method, cb) {
|
|
189
|
-
return async (req, res, next)=>{
|
|
190
|
-
const m = req.method?.toUpperCase();
|
|
191
|
-
if (m === method) {
|
|
192
|
-
try {
|
|
193
|
-
const body = await cb(req, res, next);
|
|
194
|
-
res.statusCode = 200;
|
|
195
|
-
if (Buffer.isBuffer(body)) {
|
|
196
|
-
res.setHeader('Content-Length', body.byteLength);
|
|
197
|
-
const ps = new PassThrough();
|
|
198
|
-
ps.write(body);
|
|
199
|
-
ps.end();
|
|
200
|
-
ps.pipe(res);
|
|
201
|
-
} else if (body && 'object' == typeof body) {
|
|
202
|
-
res.writeHead(200, {
|
|
203
|
-
'Content-Type': 'application/json;utf-8'
|
|
204
|
-
});
|
|
205
|
-
res.write(JSON.stringify(body));
|
|
206
|
-
res.end();
|
|
207
|
-
} else res.writeHead(200).end(body);
|
|
208
|
-
} catch (error) {
|
|
209
|
-
res.statusCode = 500;
|
|
210
|
-
res.end(error.message);
|
|
211
|
-
return next(error);
|
|
212
|
-
}
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
await next();
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
proxy(api, method, cb) {
|
|
219
|
-
let idx = this.app.stack.findIndex((e)=>e.route === api);
|
|
220
|
-
if (-1 === idx) idx = this.app.stack.length - 1;
|
|
221
|
-
this.app.stack.splice(idx, 0, {
|
|
222
|
-
route: api,
|
|
223
|
-
handle: this.wrapNextHandleFunction(method, cb)
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
getClientUrl(route = 'homepage', ...args) {
|
|
227
|
-
const relativeUrl = SDK.ServerAPI.API.EntryHtml;
|
|
228
|
-
switch(route){
|
|
229
|
-
case Client.RsdoctorClientRoutes.BundleDiff:
|
|
230
|
-
{
|
|
231
|
-
const [baseline, current] = args;
|
|
232
|
-
const qs = Bundle.getBundleDiffPageQueryString([
|
|
233
|
-
baseline,
|
|
234
|
-
current
|
|
235
|
-
]);
|
|
236
|
-
return `${relativeUrl}${qs}#${Client.RsdoctorClientRoutes.BundleDiff}`;
|
|
237
|
-
}
|
|
238
|
-
default:
|
|
239
|
-
return relativeUrl;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
async openClientPage(...args) {
|
|
243
|
-
const relativeUrl = this.getClientUrl(...args);
|
|
244
|
-
const needEncodeURI = args[0] === Client.RsdoctorClientRoutes.BundleDiff;
|
|
245
|
-
const url = `http://${this.host}:${this.port}${relativeUrl}`;
|
|
246
|
-
const localhostUrl = `http://localhost:${this.port}${relativeUrl}`;
|
|
247
|
-
await openBrowser(localhostUrl, !needEncodeURI);
|
|
248
|
-
if (this._printServerUrl) logger.info(`${chalk.green(`${this.sdk.name} compiler's`)} analyzer running on: ${chalk.cyan(url)}`);
|
|
249
|
-
}
|
|
250
|
-
sendAPIDataToClient(api, msg) {
|
|
251
|
-
this._socket?.sendAPIData(api, msg);
|
|
252
|
-
}
|
|
253
|
-
async broadcast() {
|
|
254
|
-
await this._socket?.broadcast();
|
|
255
|
-
}
|
|
256
|
-
constructor(sdk, port = Server.defaultPort, config){
|
|
257
|
-
this.sdk = sdk;
|
|
258
|
-
this.disposed = true;
|
|
259
|
-
this._socketToken = randomBytes(16).toString('hex');
|
|
260
|
-
this.get = (route, cb)=>{
|
|
261
|
-
const { app } = this;
|
|
262
|
-
app.use(route, this.wrapNextHandleFunction('GET', cb));
|
|
263
|
-
return app;
|
|
264
|
-
};
|
|
265
|
-
this.post = (route, cb)=>{
|
|
266
|
-
const { app } = this;
|
|
267
|
-
app.use(route, this.wrapNextHandleFunction('POST', cb));
|
|
268
|
-
return app;
|
|
269
|
-
};
|
|
270
|
-
this.dispose = async (exitCode)=>{
|
|
271
|
-
if (this.disposed) {
|
|
272
|
-
if (void 0 !== exitCode) process.exit(exitCode);
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
this.disposed = true;
|
|
276
|
-
if (this._server) await this._server.close();
|
|
277
|
-
if (this._socket) this._socket.dispose();
|
|
278
|
-
if (void 0 !== exitCode) process.exit(exitCode);
|
|
279
|
-
};
|
|
280
|
-
assert('number' == typeof port);
|
|
281
|
-
this.port = port;
|
|
282
|
-
this._router = new Router({
|
|
283
|
-
sdk,
|
|
284
|
-
server: this,
|
|
285
|
-
apis: Object.values(__rspack_external__apis_index_js_275823d6)
|
|
286
|
-
});
|
|
287
|
-
this._innerClientPath = config?.innerClientPath || '';
|
|
288
|
-
this._printServerUrl = config?.printServerUrl ?? true;
|
|
289
|
-
this._cors = config?.cors;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
export { RsdoctorServer };
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import "node:module";
|
|
2
|
-
import raw_body from "raw-body";
|
|
3
|
-
import { createBrotliDecompress, createGunzip, createInflate } from "node:zlib";
|
|
4
|
-
const JSON_CONTENT_TYPE = 'application/json';
|
|
5
|
-
const DEFAULT_CHARSET = 'utf-8';
|
|
6
|
-
function createHttpError(status, message, type) {
|
|
7
|
-
return Object.assign(new Error(message), {
|
|
8
|
-
status,
|
|
9
|
-
statusCode: status,
|
|
10
|
-
type
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
function hasBody(req) {
|
|
14
|
-
return void 0 !== req.headers['transfer-encoding'] || !Number.isNaN(Number(req.headers['content-length']));
|
|
15
|
-
}
|
|
16
|
-
function getContentType(req) {
|
|
17
|
-
const contentType = req.headers['content-type'];
|
|
18
|
-
if ('string' != typeof contentType) return;
|
|
19
|
-
return contentType;
|
|
20
|
-
}
|
|
21
|
-
function shouldParse(req) {
|
|
22
|
-
const contentType = getContentType(req);
|
|
23
|
-
if (!contentType) return false;
|
|
24
|
-
return contentType.split(';', 1)[0].trim().toLowerCase() === JSON_CONTENT_TYPE;
|
|
25
|
-
}
|
|
26
|
-
function getCharset(req) {
|
|
27
|
-
const contentType = getContentType(req);
|
|
28
|
-
const match = contentType?.match(/(?:^|;)\s*charset\s*=\s*(?:"([^"]+)"|([^;\s]+))/i);
|
|
29
|
-
return (match?.[1] || match?.[2] || DEFAULT_CHARSET).toLowerCase();
|
|
30
|
-
}
|
|
31
|
-
function getContentStream(req) {
|
|
32
|
-
const contentEncoding = req.headers['content-encoding'];
|
|
33
|
-
const encoding = 'string' == typeof contentEncoding ? contentEncoding.toLowerCase() : 'identity';
|
|
34
|
-
if ('identity' === encoding) return {
|
|
35
|
-
stream: req,
|
|
36
|
-
length: req.headers['content-length']
|
|
37
|
-
};
|
|
38
|
-
let stream;
|
|
39
|
-
switch(encoding){
|
|
40
|
-
case 'gzip':
|
|
41
|
-
stream = createGunzip();
|
|
42
|
-
break;
|
|
43
|
-
case 'deflate':
|
|
44
|
-
stream = createInflate();
|
|
45
|
-
break;
|
|
46
|
-
case 'br':
|
|
47
|
-
stream = createBrotliDecompress();
|
|
48
|
-
break;
|
|
49
|
-
default:
|
|
50
|
-
throw createHttpError(415, `unsupported content encoding "${encoding}"`, 'encoding.unsupported');
|
|
51
|
-
}
|
|
52
|
-
const cleanup = ()=>{
|
|
53
|
-
req.removeListener('aborted', onAborted);
|
|
54
|
-
req.removeListener('close', onClose);
|
|
55
|
-
req.removeListener('error', onError);
|
|
56
|
-
stream.removeListener('close', cleanup);
|
|
57
|
-
};
|
|
58
|
-
const destroy = (error)=>{
|
|
59
|
-
if (!stream.destroyed) stream.destroy(error);
|
|
60
|
-
};
|
|
61
|
-
const onAborted = ()=>{
|
|
62
|
-
destroy(createHttpError(400, 'request aborted', 'request.aborted'));
|
|
63
|
-
};
|
|
64
|
-
const onClose = ()=>{
|
|
65
|
-
if (false === req.complete) onAborted();
|
|
66
|
-
};
|
|
67
|
-
const onError = (error)=>{
|
|
68
|
-
destroy(error);
|
|
69
|
-
};
|
|
70
|
-
req.once('aborted', onAborted);
|
|
71
|
-
req.once('close', onClose);
|
|
72
|
-
req.once('error', onError);
|
|
73
|
-
stream.once('close', cleanup);
|
|
74
|
-
req.pipe(stream);
|
|
75
|
-
return {
|
|
76
|
-
stream,
|
|
77
|
-
cleanup,
|
|
78
|
-
decompressor: stream
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
function parseJson(body) {
|
|
82
|
-
if (0 === body.length) return {};
|
|
83
|
-
let value;
|
|
84
|
-
try {
|
|
85
|
-
value = JSON.parse(body);
|
|
86
|
-
} catch (error) {
|
|
87
|
-
throw createHttpError(400, error.message, 'entity.parse.failed');
|
|
88
|
-
}
|
|
89
|
-
if (null === value || 'object' != typeof value) throw createHttpError(400, 'JSON body must be an object or array', 'entity.parse.failed');
|
|
90
|
-
return value;
|
|
91
|
-
}
|
|
92
|
-
function normalizeReadError(error, charset) {
|
|
93
|
-
if (error instanceof Error && 'status' in error && 'number' == typeof error.status) {
|
|
94
|
-
if (charset && 'type' in error && 'encoding.unsupported' === error.type) return createHttpError(415, `unsupported charset "${charset.toUpperCase()}"`, 'charset.unsupported');
|
|
95
|
-
return error;
|
|
96
|
-
}
|
|
97
|
-
return createHttpError(400, error instanceof Error ? error.message : 'failed to read request body', 'request.invalid');
|
|
98
|
-
}
|
|
99
|
-
function jsonBodyParser(options = {}) {
|
|
100
|
-
return (req, _res, next)=>{
|
|
101
|
-
const request = req;
|
|
102
|
-
if (!('body' in request)) request.body = void 0;
|
|
103
|
-
if (!hasBody(req) || !shouldParse(req)) return void next();
|
|
104
|
-
const charset = getCharset(req);
|
|
105
|
-
if (!charset.startsWith('utf-')) {
|
|
106
|
-
req.resume();
|
|
107
|
-
next(createHttpError(415, `unsupported charset "${charset.toUpperCase()}"`, 'charset.unsupported'));
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
let content;
|
|
111
|
-
try {
|
|
112
|
-
content = getContentStream(req);
|
|
113
|
-
} catch (error) {
|
|
114
|
-
req.resume();
|
|
115
|
-
next(normalizeReadError(error));
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
const handleError = (error)=>{
|
|
119
|
-
content.cleanup?.();
|
|
120
|
-
if (content.decompressor) {
|
|
121
|
-
req.unpipe(content.decompressor);
|
|
122
|
-
content.decompressor.destroy();
|
|
123
|
-
}
|
|
124
|
-
req.resume();
|
|
125
|
-
next(normalizeReadError(error, charset));
|
|
126
|
-
};
|
|
127
|
-
let limit;
|
|
128
|
-
try {
|
|
129
|
-
limit = 'function' == typeof options.limit ? options.limit(req) : options.limit;
|
|
130
|
-
} catch (error) {
|
|
131
|
-
handleError(error);
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
|
-
raw_body(content.stream, {
|
|
135
|
-
encoding: charset,
|
|
136
|
-
length: content.length,
|
|
137
|
-
limit
|
|
138
|
-
}).then((body)=>{
|
|
139
|
-
try {
|
|
140
|
-
request.body = parseJson(body);
|
|
141
|
-
} catch (error) {
|
|
142
|
-
handleError(error);
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
content.cleanup?.();
|
|
146
|
-
next();
|
|
147
|
-
}, handleError);
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
export { jsonBodyParser };
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import "node:module";
|
|
2
|
-
const normalizeAPIKey = (key)=>{
|
|
3
|
-
if (key && 'object' == typeof key && 'name' in key) return key.name;
|
|
4
|
-
return key;
|
|
5
|
-
};
|
|
6
|
-
class Router {
|
|
7
|
-
static get(pathname) {
|
|
8
|
-
return (target, propertyKey, descriptor)=>{
|
|
9
|
-
const routes = Router.routes.get;
|
|
10
|
-
const constructor = target.constructor;
|
|
11
|
-
if (!routes.has(constructor)) routes.set(constructor, []);
|
|
12
|
-
routes.get(constructor).push([
|
|
13
|
-
normalizeAPIKey(propertyKey),
|
|
14
|
-
pathname
|
|
15
|
-
]);
|
|
16
|
-
return descriptor;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
static post(pathname) {
|
|
20
|
-
return (target, propertyKey, descriptor)=>{
|
|
21
|
-
const routes = Router.routes.post;
|
|
22
|
-
const constructor = target.constructor;
|
|
23
|
-
if (!routes.has(constructor)) routes.set(constructor, []);
|
|
24
|
-
routes.get(constructor).push([
|
|
25
|
-
normalizeAPIKey(propertyKey),
|
|
26
|
-
pathname
|
|
27
|
-
]);
|
|
28
|
-
return descriptor;
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
async setup() {
|
|
32
|
-
const { apis, sdk, server } = this.options;
|
|
33
|
-
apis.forEach((API)=>{
|
|
34
|
-
const obj = new API(sdk, server);
|
|
35
|
-
Router.routes.get.get(API)?.forEach(([key, pathname])=>{
|
|
36
|
-
server.get(pathname, this.wrapAPIFunction(obj, key));
|
|
37
|
-
});
|
|
38
|
-
Router.routes.post.get(API)?.forEach(([key, pathname])=>{
|
|
39
|
-
server.post(pathname, this.wrapAPIFunction(obj, key));
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
wrapAPIFunction(api, key) {
|
|
44
|
-
const { sdk, server } = this.options;
|
|
45
|
-
return async (req, res)=>{
|
|
46
|
-
const ctx = {
|
|
47
|
-
req,
|
|
48
|
-
res,
|
|
49
|
-
sdk,
|
|
50
|
-
server
|
|
51
|
-
};
|
|
52
|
-
const trap = new Proxy(api, {
|
|
53
|
-
get (target, key, receiver) {
|
|
54
|
-
switch(key){
|
|
55
|
-
case 'ctx':
|
|
56
|
-
return ctx;
|
|
57
|
-
default:
|
|
58
|
-
return Reflect.get(target, key, receiver);
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
set (target, key, value, receiver) {
|
|
62
|
-
return Reflect.set(target, key, value, receiver);
|
|
63
|
-
},
|
|
64
|
-
defineProperty (target, p, attrs) {
|
|
65
|
-
return Reflect.defineProperty(target, p, attrs);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
const fn = api[key];
|
|
69
|
-
const result = await fn.call(trap, trap);
|
|
70
|
-
if ('string' == typeof result) return Buffer.from(result, 'utf-8');
|
|
71
|
-
if (result && 'object' == typeof result) return Buffer.from(JSON.stringify(result), 'utf-8');
|
|
72
|
-
return result;
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
constructor(options){
|
|
76
|
-
this.options = options;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
Router.routes = {
|
|
80
|
-
get: new Map(),
|
|
81
|
-
post: new Map()
|
|
82
|
-
};
|
|
83
|
-
export { Router };
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import "node:module";
|
|
2
|
-
import { isIP } from "node:net";
|
|
3
|
-
import { timingSafeEqual } from "node:crypto";
|
|
4
|
-
const DEFAULT_ALLOWED_CORS_ORIGINS = /^https?:\/\/(?:(?:[^:]+\.)?localhost|127\.0\.0\.1|\[::1\])(?::\d+)?$/;
|
|
5
|
-
const LOCAL_HOSTNAMES = /^(?:localhost|[^:]+\.localhost)$/;
|
|
6
|
-
function isAllowedRequestOrigin(origin) {
|
|
7
|
-
if (void 0 === origin) return true;
|
|
8
|
-
return 'string' == typeof origin && DEFAULT_ALLOWED_CORS_ORIGINS.test(origin);
|
|
9
|
-
}
|
|
10
|
-
function getHostnameFromOrigin(origin) {
|
|
11
|
-
try {
|
|
12
|
-
const hostname = new URL(origin).hostname.toLowerCase();
|
|
13
|
-
return hostname.startsWith('[') && hostname.endsWith(']') ? hostname.slice(1, -1) : hostname;
|
|
14
|
-
} catch {
|
|
15
|
-
return '';
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function isIpAddress(hostname) {
|
|
19
|
-
return 0 !== isIP(hostname);
|
|
20
|
-
}
|
|
21
|
-
function getHostnameFromHost(host) {
|
|
22
|
-
if (host.startsWith('[')) {
|
|
23
|
-
const endIndex = host.indexOf(']');
|
|
24
|
-
return -1 === endIndex ? '' : host.slice(1, endIndex);
|
|
25
|
-
}
|
|
26
|
-
return host.split(':')[0];
|
|
27
|
-
}
|
|
28
|
-
function isAllowedRequestHost(host) {
|
|
29
|
-
if ('string' != typeof host) return false;
|
|
30
|
-
const hostname = getHostnameFromHost(host).toLowerCase();
|
|
31
|
-
return LOCAL_HOSTNAMES.test(hostname) || isIpAddress(hostname);
|
|
32
|
-
}
|
|
33
|
-
function isAllowedCorsRequest(origin, host) {
|
|
34
|
-
if (void 0 === origin) return true;
|
|
35
|
-
if ('string' != typeof origin || 'string' != typeof host || !isAllowedRequestOrigin(origin)) return false;
|
|
36
|
-
const originHostname = getHostnameFromOrigin(origin);
|
|
37
|
-
const hostHostname = getHostnameFromHost(host).toLowerCase();
|
|
38
|
-
if (originHostname.endsWith('.localhost')) return originHostname === hostHostname;
|
|
39
|
-
return true;
|
|
40
|
-
}
|
|
41
|
-
function isAllowedOpenInEditorToken(token, expectedToken) {
|
|
42
|
-
if ('string' != typeof token || !expectedToken) return false;
|
|
43
|
-
const tokenBuffer = Buffer.from(token);
|
|
44
|
-
const expectedTokenBuffer = Buffer.from(expectedToken);
|
|
45
|
-
return tokenBuffer.length === expectedTokenBuffer.length && timingSafeEqual(tokenBuffer, expectedTokenBuffer);
|
|
46
|
-
}
|
|
47
|
-
export { DEFAULT_ALLOWED_CORS_ORIGINS, isAllowedCorsRequest, isAllowedOpenInEditorToken, isAllowedRequestHost, isAllowedRequestOrigin };
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import "node:module";
|
|
2
|
-
import { Data } from "../../../common/index.js";
|
|
3
|
-
class SocketAPILoader {
|
|
4
|
-
async loadManifest() {
|
|
5
|
-
return this.options.sdk.getManifestData();
|
|
6
|
-
}
|
|
7
|
-
async loadData(key) {
|
|
8
|
-
const data = this.options.sdk.getStoreData();
|
|
9
|
-
const sep = '.';
|
|
10
|
-
let res = data[key];
|
|
11
|
-
if (key.includes(sep)) res = key.split(sep).reduce((t, k)=>t[k], data);
|
|
12
|
-
return res;
|
|
13
|
-
}
|
|
14
|
-
get loadAPIData() {
|
|
15
|
-
return this.dataLoader.loadAPI;
|
|
16
|
-
}
|
|
17
|
-
constructor(options){
|
|
18
|
-
this.options = options;
|
|
19
|
-
this.dataLoader = new Data.APIDataLoader(this);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
export { SocketAPILoader };
|