@teardown/cli 1.2.33 → 1.2.35

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 (40) hide show
  1. package/dist/commands/dev/dev.js +55 -0
  2. package/dist/commands/init/init-teardown.js +26 -0
  3. package/dist/index.js +20 -0
  4. package/dist/modules/dev/dev-menu/keyboard-handler.js +138 -0
  5. package/dist/modules/dev/dev-menu/open-debugger-keyboard-handler.js +105 -0
  6. package/dist/modules/dev/dev-server/cdp/cdp.adapter.js +12 -0
  7. package/dist/modules/dev/dev-server/cdp/index.js +18 -0
  8. package/dist/modules/dev/dev-server/cdp/types.js +2 -0
  9. package/dist/modules/dev/dev-server/dev-server-checker.js +72 -0
  10. package/dist/modules/dev/dev-server/dev-server.js +269 -0
  11. package/dist/modules/dev/dev-server/inspector/device.event-reporter.js +165 -0
  12. package/dist/modules/dev/dev-server/inspector/device.js +577 -0
  13. package/dist/modules/dev/dev-server/inspector/inspector.js +204 -0
  14. package/dist/modules/dev/dev-server/inspector/types.js +2 -0
  15. package/dist/modules/dev/dev-server/inspector/wss/servers/debugger-connection.server.js +61 -0
  16. package/dist/modules/dev/dev-server/inspector/wss/servers/device-connection.server.js +64 -0
  17. package/dist/modules/dev/dev-server/plugins/devtools.plugin.js +50 -0
  18. package/dist/modules/dev/dev-server/plugins/favicon.plugin.js +19 -0
  19. package/dist/modules/dev/dev-server/plugins/multipart.plugin.js +62 -0
  20. package/dist/modules/dev/dev-server/plugins/systrace.plugin.js +28 -0
  21. package/dist/modules/dev/dev-server/plugins/types.js +2 -0
  22. package/dist/modules/dev/dev-server/plugins/wss/index.js +19 -0
  23. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-api.server.js +66 -0
  24. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-debugger.server.js +128 -0
  25. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-dev-client.server.js +75 -0
  26. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-events.server.js +198 -0
  27. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-hmr.server.js +120 -0
  28. package/dist/modules/dev/dev-server/plugins/wss/servers/web-socket-message.server.js +357 -0
  29. package/dist/modules/dev/dev-server/plugins/wss/types.js +2 -0
  30. package/dist/modules/dev/dev-server/plugins/wss/web-socket-router.js +57 -0
  31. package/dist/modules/dev/dev-server/plugins/wss/web-socket-server-adapter.js +26 -0
  32. package/dist/modules/dev/dev-server/plugins/wss/web-socket-server.js +46 -0
  33. package/dist/modules/dev/dev-server/plugins/wss/wss.plugin.js +55 -0
  34. package/dist/modules/dev/dev-server/sybmolicate/sybmolicate.plugin.js +36 -0
  35. package/dist/modules/dev/dev-server/sybmolicate/types.js +2 -0
  36. package/dist/modules/dev/terminal/base.terminal.reporter.js +78 -0
  37. package/dist/modules/dev/terminal/terminal.reporter.js +76 -0
  38. package/dist/modules/dev/types.js +2 -0
  39. package/dist/modules/dev/utils/log.js +73 -0
  40. package/package.json +1 -1
@@ -0,0 +1,269 @@
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
+ exports.DevServer = void 0;
7
+ exports.makeLogEntryFromFastifyLog = makeLogEntryFromFastifyLog;
8
+ const compress_1 = __importDefault(require("@fastify/compress"));
9
+ const cors_1 = __importDefault(require("@fastify/cors"));
10
+ const middie_1 = __importDefault(require("@fastify/middie"));
11
+ const sensible_1 = __importDefault(require("@fastify/sensible"));
12
+ const cli_server_api_1 = require("@react-native-community/cli-server-api");
13
+ const metro_config_1 = require("@react-native/metro-config");
14
+ const fastify_1 = __importDefault(require("fastify"));
15
+ const metro_1 = __importDefault(require("metro"));
16
+ const node_stream_1 = require("node:stream");
17
+ const keyboard_handler_1 = require("../dev-menu/keyboard-handler");
18
+ const terminal_reporter_1 = require("../terminal/terminal.reporter");
19
+ const inspector_1 = require("./inspector/inspector");
20
+ const devtools_plugin_1 = require("./plugins/devtools.plugin");
21
+ const favicon_plugin_1 = require("./plugins/favicon.plugin");
22
+ const multipart_plugin_1 = require("./plugins/multipart.plugin");
23
+ const systrace_plugin_1 = require("./plugins/systrace.plugin");
24
+ const wss_1 = require("./plugins/wss");
25
+ const web_socket_api_server_1 = require("./plugins/wss/servers/web-socket-api.server");
26
+ const web_socket_events_server_1 = require("./plugins/wss/servers/web-socket-events.server");
27
+ const web_socket_message_server_1 = require("./plugins/wss/servers/web-socket-message.server");
28
+ const sybmolicate_plugin_1 = require("./sybmolicate/sybmolicate.plugin");
29
+ class DevServer {
30
+ config;
31
+ terminalReporter;
32
+ stream;
33
+ instance;
34
+ apiServer;
35
+ messageServer;
36
+ eventsServer;
37
+ keyboardHandler;
38
+ inspector;
39
+ constructor(config) {
40
+ this.config = config;
41
+ this.terminalReporter = new terminal_reporter_1.TeardownTerminalReporter(this);
42
+ this.stream = new node_stream_1.Writable({
43
+ write: this.onWrite.bind(this),
44
+ });
45
+ this.instance = (0, fastify_1.default)({
46
+ // disableRequestLogging: true,
47
+ logger: {
48
+ level: "trace",
49
+ stream: this.stream,
50
+ },
51
+ ...(config.https ? { https: config.https } : undefined),
52
+ });
53
+ this.apiServer = new web_socket_api_server_1.WebSocketApiServer(this.instance);
54
+ this.messageServer = new web_socket_message_server_1.WebSocketMessageServer(this.instance);
55
+ this.eventsServer = new web_socket_events_server_1.WebSocketEventsServer(this.instance, {
56
+ webSocketMessageServer: this.messageServer,
57
+ });
58
+ this.keyboardHandler = new keyboard_handler_1.KeyboardHandlerManager(this);
59
+ this.inspector = new inspector_1.Inspector({
60
+ projectRoot: this.config.projectRoot,
61
+ serverBaseUrl: this.getDevServerUrl(),
62
+ // eventReporter: this.terminalReporter,
63
+ });
64
+ }
65
+ async onWrite(chunk, encoding, callback) {
66
+ if (chunk == null) {
67
+ return;
68
+ }
69
+ const log = JSON.parse(chunk.toString());
70
+ this.apiServer.send(log);
71
+ callback();
72
+ }
73
+ getDevServerUrl() {
74
+ const https = this.config.https ? "https" : "http";
75
+ return `${https}://${this.config.host}:${this.config.port}`;
76
+ }
77
+ onInitializeDone() {
78
+ this.keyboardHandler.initialize();
79
+ }
80
+ reportMetroEvent(event) {
81
+ this.apiServer.send({
82
+ type: "metro_event",
83
+ event,
84
+ });
85
+ switch (event.type) {
86
+ case "client_log":
87
+ this.eventsServer.broadcastEvent(event);
88
+ break;
89
+ }
90
+ }
91
+ onBundleBuilt(bundlePath) {
92
+ // console.log("onBundleBuilt", bundlePath);
93
+ // this.messageServer.broadcast("reload");
94
+ }
95
+ onClientConnected(platform, clientId) {
96
+ // this.messageServer.broadcast("reload", undefined, []);
97
+ // this.instance.wss.router.onClientConnected(platform, clientId);
98
+ // this.onMessage({
99
+ // level: 30,
100
+ // time: Date.now(),
101
+ // pid: 1,
102
+ // hostname: "localhost",
103
+ // });
104
+ }
105
+ async loadMetroConfig() {
106
+ const config = await metro_1.default.loadConfig({
107
+ cwd: this.config.projectRoot,
108
+ ...this.config,
109
+ });
110
+ const reactNativeConfig = (0, metro_config_1.getDefaultConfig)(this.config.projectRoot);
111
+ return (0, metro_config_1.mergeConfig)(reactNativeConfig, config);
112
+ }
113
+ _metroConfig = null;
114
+ async getMetroConfig() {
115
+ if (!this._metroConfig) {
116
+ this._metroConfig = await this.loadMetroConfig();
117
+ }
118
+ return (0, metro_config_1.mergeConfig)(this._metroConfig, {
119
+ reporter: this.terminalReporter,
120
+ });
121
+ }
122
+ async registerPlugins() {
123
+ const metroConfig = await this.getMetroConfig();
124
+ const serverInstance = await metro_1.default.createConnectMiddleware(metroConfig, {
125
+ watch: true,
126
+ onBundleBuilt: this.onBundleBuilt.bind(this),
127
+ });
128
+ const websockets = this.inspector.createWebSocketServers();
129
+ // const devMiddleware = createDevMiddleware({
130
+ // projectRoot: this.config.projectRoot,
131
+ // serverBaseUrl: `http://${this.config.host}:${this.config.port}`,
132
+ // logger: this.instance.log,
133
+ // unstable_customInspectorMessageHandler:
134
+ // this.customInspectorMessageHandler.bind(this),
135
+ // unstable_experiments: {
136
+ // enableNetworkInspector: true,
137
+ // },
138
+ // });
139
+ // const debuggerConnectionServer = new DebuggerConnectionServer({
140
+ // devices: this.devices,
141
+ // eventReporter: this.eventReporter,
142
+ // startHeartbeat: this.startHeartbeat,
143
+ // });
144
+ // const deviceConnectionServer = new DeviceConnectionServer(this.instance);
145
+ await this.instance.register(cors_1.default, {
146
+ origin: "*",
147
+ // "localhost",
148
+ // "localhost:8081",
149
+ // "127.0.0.1",
150
+ // "127.0.0.1:8081",
151
+ // /localhost:\d+/,
152
+ // /127\.0\.0\.1:\d+/,
153
+ // ],
154
+ // methods: ["GET", "PUT", "POST", "DELETE", "OPTIONS"],
155
+ // allowedHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
156
+ // credentials: true,
157
+ // maxAge: 86400,
158
+ // preflight: true,
159
+ preflightContinue: true,
160
+ });
161
+ await this.instance.register(compress_1.default);
162
+ await this.instance.register(sensible_1.default);
163
+ await this.instance.register(middie_1.default);
164
+ await this.instance.register(wss_1.wssPlugin, {
165
+ metroConfig,
166
+ metroServer: serverInstance.metroServer,
167
+ onClientConnected: this.onClientConnected.bind(this),
168
+ messageServer: this.messageServer,
169
+ eventsServer: this.eventsServer,
170
+ apiServer: this.apiServer,
171
+ endpoints: {
172
+ "/inspector/debug": websockets["/inspector/debug"],
173
+ "/inspector/device": websockets["/inspector/device"],
174
+ "/inspector/network": websockets["/inspector/debug"],
175
+ },
176
+ });
177
+ await this.instance.register(multipart_plugin_1.multipartPlugin);
178
+ await this.instance.register(devtools_plugin_1.devtoolsPlugin, {
179
+ host: this.config.host,
180
+ port: this.config.port,
181
+ https: this.config.https,
182
+ });
183
+ await this.instance.register(sybmolicate_plugin_1.symbolicatePlugin, {
184
+ onSymbolicate: this.onSymbolicate.bind(this),
185
+ });
186
+ await this.instance.register(systrace_plugin_1.systracePlugin);
187
+ await this.instance.register(favicon_plugin_1.faviconPlugin);
188
+ // Register middleware
189
+ this.instance.use("/open-url", cli_server_api_1.openURLMiddleware);
190
+ this.instance.use("/open-stack-frame", (0, cli_server_api_1.openStackFrameInEditorMiddleware)({
191
+ watchFolders: [this.config.projectRoot],
192
+ }));
193
+ this.instance.use(serverInstance.metroServer.processRequest);
194
+ this.instance.use((req, resp, next) => this.inspector.handleHttpRequest(req, resp, next));
195
+ }
196
+ onSymbolicate(request, reply) {
197
+ const result = JSON.parse(request.rawBody);
198
+ const { codeFrame, stack } = result;
199
+ this.instance.log.info("onSymbolicate", { codeFrame, stack });
200
+ }
201
+ registerHooks() {
202
+ this.instance.log.info("Registering hooks");
203
+ this.instance = this.instance.addHook("onSend", async (request, reply, payload) => {
204
+ reply.header("X-Content-Type-Options", "nosniff");
205
+ reply.header("X-React-Native-Project-Root", this.config.projectRoot);
206
+ const [pathname] = request.url.split("?");
207
+ if (pathname.endsWith(".map")) {
208
+ reply.header("Access-Control-Allow-Origin", "devtools://devtools");
209
+ }
210
+ return payload;
211
+ });
212
+ this.instance.log.info("Hooks registered");
213
+ }
214
+ registerRoutes() {
215
+ this.instance.log.info("Registering routes");
216
+ this.instance.get("/", async () => "React Native packager is running");
217
+ this.instance.get("/status", async () => "packager-status:running");
218
+ this.instance.log.info("Routes registered");
219
+ }
220
+ async initialize() {
221
+ this.instance.log.info("Initializing dev server");
222
+ await this.registerPlugins();
223
+ this.registerHooks();
224
+ this.registerRoutes();
225
+ this.instance.log.info("Dev server initialized");
226
+ }
227
+ async start() {
228
+ this.instance.log.info("Starting dev server", this.config);
229
+ await this.instance.listen({
230
+ port: this.config.port,
231
+ host: this.config.host,
232
+ });
233
+ this.instance.log.info("Dev server started", this.instance.server.address());
234
+ }
235
+ async stop() {
236
+ this.instance.log.info("Stopping dev server");
237
+ await this.instance.close();
238
+ this.instance.log.info("Dev server stopped");
239
+ }
240
+ getInstance() {
241
+ return this.instance;
242
+ }
243
+ }
244
+ exports.DevServer = DevServer;
245
+ const levelToTypeMapping = {
246
+ 10: "debug",
247
+ 20: "debug",
248
+ 30: "info",
249
+ 40: "warn",
250
+ 50: "error",
251
+ 60: "error",
252
+ };
253
+ function makeLogEntryFromFastifyLog(data) {
254
+ const { level, time, pid, hostname, ...rest } = data;
255
+ const levelToTypeMapping = {
256
+ 10: "debug",
257
+ 20: "debug",
258
+ 30: "info",
259
+ 40: "warn",
260
+ 50: "error",
261
+ 60: "error",
262
+ };
263
+ return {
264
+ type: levelToTypeMapping[level] ?? "log",
265
+ timestamp: time,
266
+ issuer: "",
267
+ message: [rest],
268
+ };
269
+ }
@@ -0,0 +1,165 @@
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
+ exports.DeviceEventReporter = void 0;
7
+ const ttlcache_1 = __importDefault(require("@isaacs/ttlcache"));
8
+ class DeviceEventReporter {
9
+ eventReporter;
10
+ metadata;
11
+ pendingCommands;
12
+ constructor(eventReporter, metadata) {
13
+ this.eventReporter = eventReporter;
14
+ this.metadata = metadata;
15
+ this.pendingCommands = new ttlcache_1.default({
16
+ ttl: 10000,
17
+ dispose: (command, id, reason) => {
18
+ if (reason === "delete" || reason === "set") {
19
+ // TODO: Report clobbering ('set') using a dedicated error code
20
+ return;
21
+ }
22
+ this.logExpiredCommand(command);
23
+ },
24
+ });
25
+ }
26
+ logRequest(req, origin, metadata) {
27
+ this.pendingCommands.set(req.id, {
28
+ method: req.method,
29
+ requestOrigin: origin,
30
+ requestTime: Date.now(),
31
+ metadata,
32
+ });
33
+ }
34
+ logResponse(res, origin, metadata) {
35
+ const pendingCommand = this.pendingCommands.get(res.id);
36
+ if (!pendingCommand) {
37
+ this.eventReporter.logEvent({
38
+ type: "debugger_command",
39
+ protocol: "CDP",
40
+ requestOrigin: null,
41
+ method: null,
42
+ status: "coded_error",
43
+ errorCode: "UNMATCHED_REQUEST_ID",
44
+ responseOrigin: origin,
45
+ timeSinceStart: null,
46
+ appId: this.metadata.appId,
47
+ deviceId: this.metadata.deviceId,
48
+ deviceName: this.metadata.deviceName,
49
+ pageId: metadata.pageId,
50
+ frontendUserAgent: metadata.frontendUserAgent,
51
+ prefersFuseboxFrontend: metadata.prefersFuseboxFrontend,
52
+ });
53
+ return;
54
+ }
55
+ const timeSinceStart = Date.now() - pendingCommand.requestTime;
56
+ this.pendingCommands.delete(res.id);
57
+ if (res.error) {
58
+ let message = res.error.message;
59
+ if ("data" in res.error) {
60
+ message += ` (${String(res.error.data)})`;
61
+ }
62
+ this.eventReporter.logEvent({
63
+ type: "debugger_command",
64
+ requestOrigin: pendingCommand.requestOrigin,
65
+ method: pendingCommand.method,
66
+ protocol: "CDP",
67
+ status: "coded_error",
68
+ errorCode: "PROTOCOL_ERROR",
69
+ errorDetails: message,
70
+ responseOrigin: origin,
71
+ timeSinceStart,
72
+ appId: this.metadata.appId,
73
+ deviceId: this.metadata.deviceId,
74
+ deviceName: this.metadata.deviceName,
75
+ pageId: pendingCommand.metadata.pageId,
76
+ frontendUserAgent: pendingCommand.metadata.frontendUserAgent,
77
+ prefersFuseboxFrontend: metadata.prefersFuseboxFrontend,
78
+ });
79
+ return;
80
+ }
81
+ this.eventReporter.logEvent({
82
+ type: "debugger_command",
83
+ protocol: "CDP",
84
+ requestOrigin: pendingCommand.requestOrigin,
85
+ method: pendingCommand.method,
86
+ status: "success",
87
+ responseOrigin: origin,
88
+ timeSinceStart,
89
+ appId: this.metadata.appId,
90
+ deviceId: this.metadata.deviceId,
91
+ deviceName: this.metadata.deviceName,
92
+ pageId: pendingCommand.metadata.pageId,
93
+ frontendUserAgent: pendingCommand.metadata.frontendUserAgent,
94
+ prefersFuseboxFrontend: metadata.prefersFuseboxFrontend,
95
+ });
96
+ }
97
+ logConnection(connectedEntity, metadata) {
98
+ this.eventReporter.logEvent({
99
+ type: "connect_debugger_frontend",
100
+ status: "success",
101
+ appId: this.metadata.appId,
102
+ deviceName: this.metadata.deviceName,
103
+ deviceId: this.metadata.deviceId,
104
+ pageId: metadata.pageId,
105
+ frontendUserAgent: metadata.frontendUserAgent,
106
+ });
107
+ }
108
+ logDisconnection(disconnectedEntity) {
109
+ const errorCode = disconnectedEntity === "device"
110
+ ? "DEVICE_DISCONNECTED"
111
+ : "DEBUGGER_DISCONNECTED";
112
+ for (const pendingCommand of this.pendingCommands.values()) {
113
+ this.eventReporter.logEvent({
114
+ type: "debugger_command",
115
+ protocol: "CDP",
116
+ requestOrigin: pendingCommand.requestOrigin,
117
+ method: pendingCommand.method,
118
+ status: "coded_error",
119
+ errorCode,
120
+ responseOrigin: "proxy",
121
+ timeSinceStart: Date.now() - pendingCommand.requestTime,
122
+ appId: this.metadata.appId,
123
+ deviceId: this.metadata.deviceId,
124
+ deviceName: this.metadata.deviceName,
125
+ pageId: pendingCommand.metadata.pageId,
126
+ frontendUserAgent: pendingCommand.metadata.frontendUserAgent,
127
+ prefersFuseboxFrontend: pendingCommand.metadata.prefersFuseboxFrontend,
128
+ });
129
+ }
130
+ this.pendingCommands.clear();
131
+ }
132
+ logProxyMessageHandlingError(messageOrigin, error, message) {
133
+ this.eventReporter.logEvent({
134
+ type: "proxy_error",
135
+ status: "error",
136
+ messageOrigin,
137
+ message,
138
+ error: error.message,
139
+ errorStack: error.stack ?? "",
140
+ appId: this.metadata.appId,
141
+ deviceId: this.metadata.deviceId,
142
+ deviceName: this.metadata.deviceName,
143
+ pageId: null,
144
+ });
145
+ }
146
+ logExpiredCommand(pendingCommand) {
147
+ this.eventReporter.logEvent({
148
+ type: "debugger_command",
149
+ protocol: "CDP",
150
+ requestOrigin: pendingCommand.requestOrigin,
151
+ method: pendingCommand.method,
152
+ status: "coded_error",
153
+ errorCode: "TIMED_OUT",
154
+ responseOrigin: "proxy",
155
+ timeSinceStart: Date.now() - pendingCommand.requestTime,
156
+ appId: this.metadata.appId,
157
+ deviceId: this.metadata.deviceId,
158
+ deviceName: this.metadata.deviceName,
159
+ pageId: pendingCommand.metadata.pageId,
160
+ frontendUserAgent: pendingCommand.metadata.frontendUserAgent,
161
+ prefersFuseboxFrontend: pendingCommand.metadata.prefersFuseboxFrontend,
162
+ });
163
+ }
164
+ }
165
+ exports.DeviceEventReporter = DeviceEventReporter;