@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.
Files changed (167) hide show
  1. package/dist/26.js +26163 -0
  2. package/dist/630.js +1269 -0
  3. package/dist/630.js.LICENSE.txt +7 -0
  4. package/dist/build-utils/build/chunks/assetsModules.d.ts +7 -1
  5. package/dist/build-utils/build/loader/probeLoader.d.ts +7 -2
  6. package/dist/build-utils/build/utils/parseBundle.d.ts +1 -1
  7. package/dist/index.d.ts +5 -5
  8. package/dist/index.js +1725 -7
  9. package/dist/inner-plugins/constants.d.ts +1 -1
  10. package/dist/inner-plugins/plugins/base.d.ts +2 -2
  11. package/dist/logger.d.ts +2 -2
  12. package/dist/probe-loader.js +2 -0
  13. package/dist/proxy-loader.d.ts +1 -0
  14. package/dist/proxy-loader.js +48 -0
  15. package/dist/rslib-runtime.js +28 -0
  16. package/dist/rspack-plugin/constants.d.ts +1 -1
  17. package/dist/rules/rules/ecma-version-check/htmlParserStub.d.ts +3 -0
  18. package/dist/rules/rules/ecma-version-check/types.d.ts +13 -2
  19. package/dist/sdk/server/apis/base.d.ts +1 -1
  20. package/dist/sdk/server/socket/api.d.ts +1 -1
  21. package/dist/sdk/utils/date.d.ts +1 -0
  22. package/dist/types/loader.d.ts +1 -1
  23. package/package.json +20 -113
  24. package/dist/build-utils/build/chunks/assetsModules.js +0 -9
  25. package/dist/build-utils/build/chunks/index.js +0 -3
  26. package/dist/build-utils/build/chunks/rspack/transform.js +0 -44
  27. package/dist/build-utils/build/envinfo.js +0 -60
  28. package/dist/build-utils/build/file/cache.js +0 -24
  29. package/dist/build-utils/build/file/index.js +0 -5
  30. package/dist/build-utils/build/file/sharding.js +0 -38
  31. package/dist/build-utils/build/index.js +0 -12
  32. package/dist/build-utils/build/json.js +0 -67
  33. package/dist/build-utils/build/loader/index.js +0 -3
  34. package/dist/build-utils/build/loader/probeLoader.js +0 -44
  35. package/dist/build-utils/build/loader/probeLoaderPlugin.js +0 -32
  36. package/dist/build-utils/build/module-graph/index.js +0 -2
  37. package/dist/build-utils/build/module-graph/parser.js +0 -13
  38. package/dist/build-utils/build/module-graph/rspack/transform.js +0 -111
  39. package/dist/build-utils/build/module-graph/utils.js +0 -60
  40. package/dist/build-utils/build/process.js +0 -18
  41. package/dist/build-utils/build/server.js +0 -107
  42. package/dist/build-utils/build/utils/index.js +0 -4
  43. package/dist/build-utils/build/utils/loader.js +0 -267
  44. package/dist/build-utils/build/utils/parseBundle.js +0 -238
  45. package/dist/build-utils/build/utils/plugin.js +0 -21
  46. package/dist/build-utils/index.js +0 -13
  47. package/dist/collection.d.ts +0 -1
  48. package/dist/collection.js +0 -2
  49. package/dist/common/file.js +0 -8
  50. package/dist/common/global-config.js +0 -33
  51. package/dist/common/index.d.ts +0 -4
  52. package/dist/common/index.js +0 -6
  53. package/dist/common-browser.d.ts +0 -1
  54. package/dist/common-browser.js +0 -2
  55. package/dist/error/error.js +0 -143
  56. package/dist/error/index.js +0 -3
  57. package/dist/error/transform.js +0 -138
  58. package/dist/error/utils.js +0 -23
  59. package/dist/graph/index.d.ts +0 -1
  60. package/dist/graph/index.js +0 -2
  61. package/dist/inner-plugins/constants.js +0 -19
  62. package/dist/inner-plugins/index.js +0 -3
  63. package/dist/inner-plugins/loaders/proxy.js +0 -65
  64. package/dist/inner-plugins/plugins/base.js +0 -20
  65. package/dist/inner-plugins/plugins/bundle.js +0 -63
  66. package/dist/inner-plugins/plugins/ensureModulesChunkGraph.js +0 -74
  67. package/dist/inner-plugins/plugins/errors.js +0 -65
  68. package/dist/inner-plugins/plugins/index.js +0 -11
  69. package/dist/inner-plugins/plugins/loader.js +0 -108
  70. package/dist/inner-plugins/plugins/plugins.js +0 -40
  71. package/dist/inner-plugins/plugins/progress.js +0 -35
  72. package/dist/inner-plugins/plugins/resolver.js +0 -57
  73. package/dist/inner-plugins/plugins/rspack.js +0 -99
  74. package/dist/inner-plugins/plugins/rules.js +0 -64
  75. package/dist/inner-plugins/plugins/sourcemapTool.js +0 -230
  76. package/dist/inner-plugins/plugins/summary.js +0 -92
  77. package/dist/inner-plugins/utils/circleDetect.js +0 -16
  78. package/dist/inner-plugins/utils/config.js +0 -141
  79. package/dist/inner-plugins/utils/index.js +0 -8
  80. package/dist/inner-plugins/utils/loader.js +0 -134
  81. package/dist/inner-plugins/utils/normalize-config.js +0 -77
  82. package/dist/inner-plugins/utils/openBrowser.js +0 -55
  83. package/dist/inner-plugins/utils/plugin-common.js +0 -94
  84. package/dist/inner-plugins/utils/plugin.js +0 -70
  85. package/dist/inner-plugins/utils/sdk.js +0 -19
  86. package/dist/logger.js +0 -51
  87. package/dist/rspack-plugin/constants.js +0 -23
  88. package/dist/rspack-plugin/index.js +0 -3
  89. package/dist/rspack-plugin/multiple.js +0 -39
  90. package/dist/rspack-plugin/plugin.js +0 -133
  91. package/dist/rule-utils/document/document.js +0 -46
  92. package/dist/rule-utils/document/index.js +0 -4
  93. package/dist/rule-utils/document/server.js +0 -13
  94. package/dist/rule-utils/document/types.js +0 -1
  95. package/dist/rule-utils/index.js +0 -3
  96. package/dist/rule-utils/parser/asserts.js +0 -105
  97. package/dist/rule-utils/parser/index.js +0 -5
  98. package/dist/rule-utils/parser/parser.js +0 -24
  99. package/dist/rule-utils/parser/types.js +0 -8
  100. package/dist/rule-utils/parser/utils.js +0 -106
  101. package/dist/rules/index.js +0 -4
  102. package/dist/rules/linter.js +0 -36
  103. package/dist/rules/rule.js +0 -101
  104. package/dist/rules/rules/cjs-require/index.js +0 -50
  105. package/dist/rules/rules/cjs-require/types.js +0 -1
  106. package/dist/rules/rules/cross-chunks-package/index.js +0 -41
  107. package/dist/rules/rules/cross-chunks-package/types.js +0 -1
  108. package/dist/rules/rules/cross-chunks-package/utils.js +0 -7
  109. package/dist/rules/rules/default-import-check/index.js +0 -83
  110. package/dist/rules/rules/default-import-check/types.js +0 -1
  111. package/dist/rules/rules/default-import-check/utils.js +0 -52
  112. package/dist/rules/rules/duplicate-package/index.js +0 -39
  113. package/dist/rules/rules/duplicate-package/types.js +0 -24
  114. package/dist/rules/rules/duplicate-package/utils.js +0 -38
  115. package/dist/rules/rules/ecma-version-check/index.js +0 -53
  116. package/dist/rules/rules/ecma-version-check/types.js +0 -1
  117. package/dist/rules/rules/ecma-version-check/utils.js +0 -6
  118. package/dist/rules/rules/esm-resolved-to-cjs/index.js +0 -193
  119. package/dist/rules/rules/esm-resolved-to-cjs/types.js +0 -1
  120. package/dist/rules/rules/index.js +0 -22
  121. package/dist/rules/rules/loader-performance-optimization/index.js +0 -86
  122. package/dist/rules/rules/loader-performance-optimization/types.js +0 -1
  123. package/dist/rules/rules/loader-performance-optimization/utils.js +0 -10
  124. package/dist/rules/rules/module-mixed-chunks/index.js +0 -52
  125. package/dist/rules/rules/module-mixed-chunks/types.js +0 -1
  126. package/dist/rules/rules/side-effects-only-imports/index.js +0 -81
  127. package/dist/rules/rules/side-effects-only-imports/types.js +0 -1
  128. package/dist/rules/utils.js +0 -10
  129. package/dist/sdk/index.js +0 -3
  130. package/dist/sdk/multiple/controller.js +0 -42
  131. package/dist/sdk/multiple/index.js +0 -3
  132. package/dist/sdk/multiple/primary.js +0 -64
  133. package/dist/sdk/multiple/server.js +0 -14
  134. package/dist/sdk/sdk/core.js +0 -163
  135. package/dist/sdk/sdk/index.js +0 -435
  136. package/dist/sdk/sdk/types.js +0 -1
  137. package/dist/sdk/server/apis/alerts.js +0 -30
  138. package/dist/sdk/server/apis/base.js +0 -22
  139. package/dist/sdk/server/apis/bundle-diff.js +0 -51
  140. package/dist/sdk/server/apis/data.js +0 -44
  141. package/dist/sdk/server/apis/fs.js +0 -28
  142. package/dist/sdk/server/apis/graph.js +0 -116
  143. package/dist/sdk/server/apis/index.js +0 -11
  144. package/dist/sdk/server/apis/loader.js +0 -120
  145. package/dist/sdk/server/apis/plugin.js +0 -39
  146. package/dist/sdk/server/apis/project.js +0 -59
  147. package/dist/sdk/server/apis/renderer.js +0 -33
  148. package/dist/sdk/server/apis/resolver.js +0 -38
  149. package/dist/sdk/server/client.js +0 -8
  150. package/dist/sdk/server/fakeServer.js +0 -12
  151. package/dist/sdk/server/index.js +0 -292
  152. package/dist/sdk/server/json-body.js +0 -150
  153. package/dist/sdk/server/router.js +0 -83
  154. package/dist/sdk/server/security.js +0 -47
  155. package/dist/sdk/server/socket/api.js +0 -22
  156. package/dist/sdk/server/socket/index.js +0 -166
  157. package/dist/sdk/server/utils.js +0 -19
  158. package/dist/sdk/utils/base.js +0 -22
  159. package/dist/sdk/utils/constant.js +0 -4
  160. package/dist/sdk/utils/index.js +0 -4
  161. package/dist/sdk/utils/openBrowser.js +0 -53
  162. package/dist/sdk/utils/upload.js +0 -6
  163. package/dist/sdk.js +0 -2
  164. package/dist/types/index.js +0 -4
  165. package/dist/types/loader.js +0 -1
  166. package/dist/types/plugin.js +0 -1
  167. package/dist/types/rules.js +0 -1
@@ -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 };