feat(smart-app): implement complete mobile app MVP

- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
This commit is contained in:
Eric FELIXINE
2026-06-01 18:00:35 -04:00
parent 08ca495bde
commit e30ae8ed09
35578 changed files with 3703534 additions and 43 deletions

View File

@@ -0,0 +1,15 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import http from 'http';
type LaunchDevToolsOptions = {
host?: string;
port: number;
watchFolders: ReadonlyArray<string>;
};
export default function getDevToolsMiddleware(options: LaunchDevToolsOptions, isDebuggerConnected: () => boolean): (_req: http.IncomingMessage, res: http.ServerResponse) => void;
export {};
//# sourceMappingURL=devToolsMiddleware.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"devToolsMiddleware.d.ts","sourceRoot":"","sources":["../src/devToolsMiddleware.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AAoBxB,KAAK,qBAAqB,GAAG;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACrC,CAAC;AAiCF,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAC3C,OAAO,EAAE,qBAAqB,EAC9B,mBAAmB,EAAE,MAAM,OAAO,UAG1B,KAAK,eAAe,OACrB,KAAK,cAAc,UAK3B"}

View File

@@ -0,0 +1,75 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = getDevToolsMiddleware;
function _cliTools() {
const data = require("@react-native-community/cli-tools");
_cliTools = function () {
return data;
};
return data;
}
function _child_process() {
const data = require("child_process");
_child_process = function () {
return data;
};
return data;
}
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function launchDefaultDebugger(host, port, args = '') {
const hostname = host || 'localhost';
const debuggerURL = `http://${hostname}:${port}/debugger-ui${args}`;
_cliTools().logger.info('Launching Dev Tools...');
(0, _cliTools().launchDebugger)(debuggerURL);
}
function escapePath(pathname) {
// " Can escape paths with spaces in OS X, Windows, and *nix
return `"${pathname}"`;
}
function launchDevTools({
host,
port,
watchFolders
}, isDebuggerConnected) {
// Explicit config always wins
const customDebugger = process.env.REACT_DEBUGGER;
if (customDebugger) {
startCustomDebugger({
watchFolders,
customDebugger
});
} else if (!isDebuggerConnected()) {
// Debugger is not yet open; we need to open a session
launchDefaultDebugger(host, port);
}
}
function startCustomDebugger({
watchFolders,
customDebugger
}) {
const folders = watchFolders.map(escapePath).join(' ');
const command = `${customDebugger} ${folders}`;
_cliTools().logger.info('Starting custom debugger by executing:', command);
(0, _child_process().exec)(command, function (error) {
if (error !== null) {
_cliTools().logger.error('Error while starting custom debugger:', error.stack || '');
}
});
}
function getDevToolsMiddleware(options, isDebuggerConnected) {
return function devToolsMiddleware(_req, res) {
launchDevTools(options, isDebuggerConnected);
res.end('OK');
};
}
//# sourceMappingURL=devToolsMiddleware.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["launchDefaultDebugger","host","port","args","hostname","debuggerURL","logger","info","launchDebugger","escapePath","pathname","launchDevTools","watchFolders","isDebuggerConnected","customDebugger","process","env","REACT_DEBUGGER","startCustomDebugger","folders","map","join","command","exec","error","stack","getDevToolsMiddleware","options","devToolsMiddleware","_req","res","end"],"sources":["../src/devToolsMiddleware.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport http from 'http';\nimport {launchDebugger, logger} from '@react-native-community/cli-tools';\nimport {exec} from 'child_process';\n\nfunction launchDefaultDebugger(\n host: string | undefined,\n port: number,\n args = '',\n) {\n const hostname = host || 'localhost';\n const debuggerURL = `http://${hostname}:${port}/debugger-ui${args}`;\n logger.info('Launching Dev Tools...');\n launchDebugger(debuggerURL);\n}\n\nfunction escapePath(pathname: string) {\n // \" Can escape paths with spaces in OS X, Windows, and *nix\n return `\"${pathname}\"`;\n}\n\ntype LaunchDevToolsOptions = {\n host?: string;\n port: number;\n watchFolders: ReadonlyArray<string>;\n};\n\nfunction launchDevTools(\n {host, port, watchFolders}: LaunchDevToolsOptions,\n isDebuggerConnected: () => boolean,\n) {\n // Explicit config always wins\n const customDebugger = process.env.REACT_DEBUGGER;\n if (customDebugger) {\n startCustomDebugger({watchFolders, customDebugger});\n } else if (!isDebuggerConnected()) {\n // Debugger is not yet open; we need to open a session\n launchDefaultDebugger(host, port);\n }\n}\n\nfunction startCustomDebugger({\n watchFolders,\n customDebugger,\n}: {\n watchFolders: ReadonlyArray<string>;\n customDebugger: string;\n}) {\n const folders = watchFolders.map(escapePath).join(' ');\n const command = `${customDebugger} ${folders}`;\n logger.info('Starting custom debugger by executing:', command);\n exec(command, function (error) {\n if (error !== null) {\n logger.error('Error while starting custom debugger:', error.stack || '');\n }\n });\n}\n\nexport default function getDevToolsMiddleware(\n options: LaunchDevToolsOptions,\n isDebuggerConnected: () => boolean,\n) {\n return function devToolsMiddleware(\n _req: http.IncomingMessage,\n res: http.ServerResponse,\n ) {\n launchDevTools(options, isDebuggerConnected);\n res.end('OK');\n };\n}\n"],"mappings":";;;;;;AAOA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AACA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AARA;AACA;AACA;AACA;AACA;AACA;;AAKA,SAASA,qBAAqB,CAC5BC,IAAwB,EACxBC,IAAY,EACZC,IAAI,GAAG,EAAE,EACT;EACA,MAAMC,QAAQ,GAAGH,IAAI,IAAI,WAAW;EACpC,MAAMI,WAAW,GAAI,UAASD,QAAS,IAAGF,IAAK,eAAcC,IAAK,EAAC;EACnEG,kBAAM,CAACC,IAAI,CAAC,wBAAwB,CAAC;EACrC,IAAAC,0BAAc,EAACH,WAAW,CAAC;AAC7B;AAEA,SAASI,UAAU,CAACC,QAAgB,EAAE;EACpC;EACA,OAAQ,IAAGA,QAAS,GAAE;AACxB;AAQA,SAASC,cAAc,CACrB;EAACV,IAAI;EAAEC,IAAI;EAAEU;AAAmC,CAAC,EACjDC,mBAAkC,EAClC;EACA;EACA,MAAMC,cAAc,GAAGC,OAAO,CAACC,GAAG,CAACC,cAAc;EACjD,IAAIH,cAAc,EAAE;IAClBI,mBAAmB,CAAC;MAACN,YAAY;MAAEE;IAAc,CAAC,CAAC;EACrD,CAAC,MAAM,IAAI,CAACD,mBAAmB,EAAE,EAAE;IACjC;IACAb,qBAAqB,CAACC,IAAI,EAAEC,IAAI,CAAC;EACnC;AACF;AAEA,SAASgB,mBAAmB,CAAC;EAC3BN,YAAY;EACZE;AAIF,CAAC,EAAE;EACD,MAAMK,OAAO,GAAGP,YAAY,CAACQ,GAAG,CAACX,UAAU,CAAC,CAACY,IAAI,CAAC,GAAG,CAAC;EACtD,MAAMC,OAAO,GAAI,GAAER,cAAe,IAAGK,OAAQ,EAAC;EAC9Cb,kBAAM,CAACC,IAAI,CAAC,wCAAwC,EAAEe,OAAO,CAAC;EAC9D,IAAAC,qBAAI,EAACD,OAAO,EAAE,UAAUE,KAAK,EAAE;IAC7B,IAAIA,KAAK,KAAK,IAAI,EAAE;MAClBlB,kBAAM,CAACkB,KAAK,CAAC,uCAAuC,EAAEA,KAAK,CAACC,KAAK,IAAI,EAAE,CAAC;IAC1E;EACF,CAAC,CAAC;AACJ;AAEe,SAASC,qBAAqB,CAC3CC,OAA8B,EAC9Bd,mBAAkC,EAClC;EACA,OAAO,SAASe,kBAAkB,CAChCC,IAA0B,EAC1BC,GAAwB,EACxB;IACAnB,cAAc,CAACgB,OAAO,EAAEd,mBAAmB,CAAC;IAC5CiB,GAAG,CAACC,GAAG,CAAC,IAAI,CAAC;EACf,CAAC;AACH"}

View File

@@ -0,0 +1,44 @@
/// <reference types="ws" />
import connect from 'connect';
import devToolsMiddleware from './devToolsMiddleware';
import indexPageMiddleware from './indexPageMiddleware';
import openStackFrameInEditorMiddleware from './openStackFrameInEditorMiddleware';
import openURLMiddleware from './openURLMiddleware';
import rawBodyMiddleware from './rawBodyMiddleware';
import securityHeadersMiddleware from './securityHeadersMiddleware';
import statusPageMiddleware from './statusPageMiddleware';
import systraceProfileMiddleware from './systraceProfileMiddleware';
export { devToolsMiddleware };
export { indexPageMiddleware };
export { openStackFrameInEditorMiddleware };
export { openURLMiddleware };
export { rawBodyMiddleware };
export { securityHeadersMiddleware };
export { statusPageMiddleware };
export { systraceProfileMiddleware };
type MiddlewareOptions = {
host?: string;
watchFolders: ReadonlyArray<string>;
port: number;
};
export declare function createDevServerMiddleware(options: MiddlewareOptions): {
websocketEndpoints: {
'/debugger-proxy': import("ws").Server;
'/message': import("ws").Server;
'/events': import("ws").Server;
};
debuggerProxyEndpoint: {
server: import("ws").Server;
isDebuggerConnected: () => boolean;
};
messageSocketEndpoint: {
server: import("ws").Server;
broadcast: (method: string, params?: Record<string, any> | undefined) => void;
};
eventsSocketEndpoint: {
server: import("ws").Server;
reportEvent: (event: any) => void;
};
middleware: connect.Server;
};
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAGA,OAAO,OAAO,MAAM,SAAS,CAAC;AAM9B,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,gCAAgC,MAAM,oCAAoC,CAAC;AAClF,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,yBAAyB,MAAM,6BAA6B,CAAC;AACpE,OAAO,oBAAoB,MAAM,wBAAwB,CAAC;AAC1D,OAAO,yBAAyB,MAAM,6BAA6B,CAAC;AAMpE,OAAO,EAAC,kBAAkB,EAAC,CAAC;AAC5B,OAAO,EAAC,mBAAmB,EAAC,CAAC;AAC7B,OAAO,EAAC,gCAAgC,EAAC,CAAC;AAC1C,OAAO,EAAC,iBAAiB,EAAC,CAAC;AAC3B,OAAO,EAAC,iBAAiB,EAAC,CAAC;AAC3B,OAAO,EAAC,yBAAyB,EAAC,CAAC;AACnC,OAAO,EAAC,oBAAoB,EAAC,CAAC;AAC9B,OAAO,EAAC,yBAAyB,EAAC,CAAC;AAEnC,KAAK,iBAAiB,GAAG;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,iBAAiB;;;;;;;;;;;;;;;;;;;EAgDnE"}

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>React Native</title>
</head>
<body>
<p>React Native packager is running.</p>
<p><a href="https://reactnative.dev">Visit documentation</a></p>
<p><a href="./debugger-ui/">Go to Debugger UI</a></p>
</body>
</html>

View File

@@ -0,0 +1,142 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createDevServerMiddleware = createDevServerMiddleware;
Object.defineProperty(exports, "devToolsMiddleware", {
enumerable: true,
get: function () {
return _devToolsMiddleware.default;
}
});
Object.defineProperty(exports, "indexPageMiddleware", {
enumerable: true,
get: function () {
return _indexPageMiddleware.default;
}
});
Object.defineProperty(exports, "openStackFrameInEditorMiddleware", {
enumerable: true,
get: function () {
return _openStackFrameInEditorMiddleware.default;
}
});
Object.defineProperty(exports, "openURLMiddleware", {
enumerable: true,
get: function () {
return _openURLMiddleware.default;
}
});
Object.defineProperty(exports, "rawBodyMiddleware", {
enumerable: true,
get: function () {
return _rawBodyMiddleware.default;
}
});
Object.defineProperty(exports, "securityHeadersMiddleware", {
enumerable: true,
get: function () {
return _securityHeadersMiddleware.default;
}
});
Object.defineProperty(exports, "statusPageMiddleware", {
enumerable: true,
get: function () {
return _statusPageMiddleware.default;
}
});
Object.defineProperty(exports, "systraceProfileMiddleware", {
enumerable: true,
get: function () {
return _systraceProfileMiddleware.default;
}
});
function _compression() {
const data = _interopRequireDefault(require("compression"));
_compression = function () {
return data;
};
return data;
}
function _connect() {
const data = _interopRequireDefault(require("connect"));
_connect = function () {
return data;
};
return data;
}
function _errorhandler() {
const data = _interopRequireDefault(require("errorhandler"));
_errorhandler = function () {
return data;
};
return data;
}
function _nocache() {
const data = _interopRequireDefault(require("nocache"));
_nocache = function () {
return data;
};
return data;
}
function _serveStatic() {
const data = _interopRequireDefault(require("serve-static"));
_serveStatic = function () {
return data;
};
return data;
}
function _cliDebuggerUi() {
const data = require("@react-native-community/cli-debugger-ui");
_cliDebuggerUi = function () {
return data;
};
return data;
}
var _devToolsMiddleware = _interopRequireDefault(require("./devToolsMiddleware"));
var _indexPageMiddleware = _interopRequireDefault(require("./indexPageMiddleware"));
var _openStackFrameInEditorMiddleware = _interopRequireDefault(require("./openStackFrameInEditorMiddleware"));
var _openURLMiddleware = _interopRequireDefault(require("./openURLMiddleware"));
var _rawBodyMiddleware = _interopRequireDefault(require("./rawBodyMiddleware"));
var _securityHeadersMiddleware = _interopRequireDefault(require("./securityHeadersMiddleware"));
var _statusPageMiddleware = _interopRequireDefault(require("./statusPageMiddleware"));
var _systraceProfileMiddleware = _interopRequireDefault(require("./systraceProfileMiddleware"));
var _createDebuggerProxyEndpoint = _interopRequireDefault(require("./websocket/createDebuggerProxyEndpoint"));
var _createMessageSocketEndpoint = _interopRequireDefault(require("./websocket/createMessageSocketEndpoint"));
var _createEventsSocketEndpoint = _interopRequireDefault(require("./websocket/createEventsSocketEndpoint"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function createDevServerMiddleware(options) {
const debuggerProxyEndpoint = (0, _createDebuggerProxyEndpoint.default)();
const isDebuggerConnected = debuggerProxyEndpoint.isDebuggerConnected;
const messageSocketEndpoint = (0, _createMessageSocketEndpoint.default)();
const broadcast = messageSocketEndpoint.broadcast;
const eventsSocketEndpoint = (0, _createEventsSocketEndpoint.default)(broadcast);
const middleware = (0, _connect().default)().use(_securityHeadersMiddleware.default)
// @ts-ignore compression and connect types mismatch
.use((0, _compression().default)()).use((0, _nocache().default)()).use('/debugger-ui', (0, _cliDebuggerUi().debuggerUIMiddleware)()).use('/launch-js-devtools', (0, _devToolsMiddleware.default)(options, isDebuggerConnected)).use('/open-stack-frame', (0, _openStackFrameInEditorMiddleware.default)(options)).use('/open-url', _openURLMiddleware.default).use('/status', _statusPageMiddleware.default).use('/symbolicate', _rawBodyMiddleware.default)
// @ts-ignore mismatch
.use('/systrace', _systraceProfileMiddleware.default).use('/reload', (_req, res) => {
broadcast('reload');
res.end('OK');
})
// @ts-ignore mismatch
.use((0, _errorhandler().default)());
options.watchFolders.forEach(folder => {
// @ts-ignore mismatch between express and connect middleware types
middleware.use((0, _serveStatic().default)(folder));
});
return {
websocketEndpoints: {
'/debugger-proxy': debuggerProxyEndpoint.server,
'/message': messageSocketEndpoint.server,
'/events': eventsSocketEndpoint.server
},
debuggerProxyEndpoint,
messageSocketEndpoint,
eventsSocketEndpoint,
middleware
};
}
//# sourceMappingURL=index.ts.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
/// <reference types="node" />
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import http from 'http';
export default function indexPageMiddleware(req: http.IncomingMessage, res: http.ServerResponse, next: (err?: any) => void): void;
//# sourceMappingURL=indexPageMiddleware.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"indexPageMiddleware.d.ts","sourceRoot":"","sources":["../src/indexPageMiddleware.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,MAAM,CAAC,OAAO,UAAU,mBAAmB,CACzC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,QAQ1B"}

View File

@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = indexPageMiddleware;
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function indexPageMiddleware(req, res, next) {
if (req.url === '/') {
res.setHeader('Content-Type', 'text/html');
res.end(_fs().default.readFileSync(_path().default.join(__dirname, 'index.html')));
} else {
next();
}
}
//# sourceMappingURL=indexPageMiddleware.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["indexPageMiddleware","req","res","next","url","setHeader","end","fs","readFileSync","path","join","__dirname"],"sources":["../src/indexPageMiddleware.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport http from 'http';\nimport fs from 'fs';\nimport path from 'path';\n\nexport default function indexPageMiddleware(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n next: (err?: any) => void,\n) {\n if (req.url === '/') {\n res.setHeader('Content-Type', 'text/html');\n res.end(fs.readFileSync(path.join(__dirname, 'index.html')));\n } else {\n next();\n }\n}\n"],"mappings":";;;;;;AAOA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AACA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AAAwB;AARxB;AACA;AACA;AACA;AACA;AACA;;AAKe,SAASA,mBAAmB,CACzCC,GAAyB,EACzBC,GAAwB,EACxBC,IAAyB,EACzB;EACA,IAAIF,GAAG,CAACG,GAAG,KAAK,GAAG,EAAE;IACnBF,GAAG,CAACG,SAAS,CAAC,cAAc,EAAE,WAAW,CAAC;IAC1CH,GAAG,CAACI,GAAG,CAACC,aAAE,CAACC,YAAY,CAACC,eAAI,CAACC,IAAI,CAACC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;EAC9D,CAAC,MAAM;IACLR,IAAI,EAAE;EACR;AACF"}

View File

@@ -0,0 +1,7 @@
import connect from 'connect';
type Options = {
watchFolders: ReadonlyArray<string>;
};
declare const _default: (options: Options) => connect.Server;
export default _default;
//# sourceMappingURL=openStackFrameInEditorMiddleware.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"openStackFrameInEditorMiddleware.d.ts","sourceRoot":"","sources":["../src/openStackFrameInEditorMiddleware.ts"],"names":[],"mappings":"AAQA,OAAO,OAAO,MAAM,SAAS,CAAC;AAG9B,KAAK,OAAO,GAAG;IACb,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACrC,CAAC;kCAiBuB,OAAO;AAAhC,wBAIE"}

View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _cliTools() {
const data = require("@react-native-community/cli-tools");
_cliTools = function () {
return data;
};
return data;
}
function _connect() {
const data = _interopRequireDefault(require("connect"));
_connect = function () {
return data;
};
return data;
}
var _rawBodyMiddleware = _interopRequireDefault(require("./rawBodyMiddleware"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function getOpenStackFrameInEditorMiddleware({
watchFolders
}) {
return (req, res, next) => {
if (!req.rawBody) {
return next(new Error('missing request body'));
}
const frame = JSON.parse(req.rawBody);
(0, _cliTools().launchEditor)(frame.file, frame.lineNumber, watchFolders);
res.end('OK');
};
}
var _default = options => {
return (0, _connect().default)().use(_rawBodyMiddleware.default).use(getOpenStackFrameInEditorMiddleware(options));
};
exports.default = _default;
//# sourceMappingURL=openStackFrameInEditorMiddleware.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["getOpenStackFrameInEditorMiddleware","watchFolders","req","res","next","rawBody","Error","frame","JSON","parse","launchEditor","file","lineNumber","end","options","connect","use","rawBodyMiddleware"],"sources":["../src/openStackFrameInEditorMiddleware.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport http from 'http';\nimport {launchEditor} from '@react-native-community/cli-tools';\nimport connect from 'connect';\nimport rawBodyMiddleware from './rawBodyMiddleware';\n\ntype Options = {\n watchFolders: ReadonlyArray<string>;\n};\n\nfunction getOpenStackFrameInEditorMiddleware({watchFolders}: Options) {\n return (\n req: http.IncomingMessage & {rawBody?: string},\n res: http.ServerResponse,\n next: (err?: any) => void,\n ) => {\n if (!req.rawBody) {\n return next(new Error('missing request body'));\n }\n const frame = JSON.parse(req.rawBody);\n launchEditor(frame.file, frame.lineNumber, watchFolders);\n res.end('OK');\n };\n}\n\nexport default (options: Options) => {\n return connect()\n .use(rawBodyMiddleware)\n .use(getOpenStackFrameInEditorMiddleware(options));\n};\n"],"mappings":";;;;;;AAOA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AACA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AACA;AAAoD;AATpD;AACA;AACA;AACA;AACA;AACA;;AAUA,SAASA,mCAAmC,CAAC;EAACC;AAAqB,CAAC,EAAE;EACpE,OAAO,CACLC,GAA8C,EAC9CC,GAAwB,EACxBC,IAAyB,KACtB;IACH,IAAI,CAACF,GAAG,CAACG,OAAO,EAAE;MAChB,OAAOD,IAAI,CAAC,IAAIE,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAChD;IACA,MAAMC,KAAK,GAAGC,IAAI,CAACC,KAAK,CAACP,GAAG,CAACG,OAAO,CAAC;IACrC,IAAAK,wBAAY,EAACH,KAAK,CAACI,IAAI,EAAEJ,KAAK,CAACK,UAAU,EAAEX,YAAY,CAAC;IACxDE,GAAG,CAACU,GAAG,CAAC,IAAI,CAAC;EACf,CAAC;AACH;AAAC,eAEeC,OAAgB,IAAK;EACnC,OAAO,IAAAC,kBAAO,GAAE,CACbC,GAAG,CAACC,0BAAiB,CAAC,CACtBD,GAAG,CAAChB,mCAAmC,CAACc,OAAO,CAAC,CAAC;AACtD,CAAC;AAAA"}

View File

@@ -0,0 +1,4 @@
import connect from 'connect';
declare const _default: connect.Server;
export default _default;
//# sourceMappingURL=openURLMiddleware.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"openURLMiddleware.d.ts","sourceRoot":"","sources":["../src/openURLMiddleware.ts"],"names":[],"mappings":"AAQA,OAAO,OAAO,MAAM,SAAS,CAAC;;AAoB9B,wBAAuE"}

View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
function _cliTools() {
const data = require("@react-native-community/cli-tools");
_cliTools = function () {
return data;
};
return data;
}
function _connect() {
const data = _interopRequireDefault(require("connect"));
_connect = function () {
return data;
};
return data;
}
var _rawBodyMiddleware = _interopRequireDefault(require("./rawBodyMiddleware"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* Handle request from JS to open an arbitrary URL in Chrome
*/
function openURLMiddleware(req, res, next) {
if (!req.rawBody) {
return next(new Error('missing request body'));
}
const {
url
} = JSON.parse(req.rawBody);
_cliTools().logger.info(`Opening ${url}...`);
(0, _cliTools().launchDefaultBrowser)(url);
res.end('OK');
}
var _default = (0, _connect().default)().use(_rawBodyMiddleware.default).use(openURLMiddleware);
exports.default = _default;
//# sourceMappingURL=openURLMiddleware.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["openURLMiddleware","req","res","next","rawBody","Error","url","JSON","parse","logger","info","launchDefaultBrowser","end","connect","use","rawBodyMiddleware"],"sources":["../src/openURLMiddleware.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport http from 'http';\nimport {launchDefaultBrowser, logger} from '@react-native-community/cli-tools';\nimport connect from 'connect';\nimport rawBodyMiddleware from './rawBodyMiddleware';\n\n/**\n * Handle request from JS to open an arbitrary URL in Chrome\n */\nfunction openURLMiddleware(\n req: http.IncomingMessage & {rawBody?: string},\n res: http.ServerResponse,\n next: (err?: any) => void,\n) {\n if (!req.rawBody) {\n return next(new Error('missing request body'));\n }\n const {url} = JSON.parse(req.rawBody);\n logger.info(`Opening ${url}...`);\n launchDefaultBrowser(url);\n res.end('OK');\n}\n\nexport default connect().use(rawBodyMiddleware).use(openURLMiddleware);\n"],"mappings":";;;;;;AAOA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AACA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AACA;AAAoD;AATpD;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA,SAASA,iBAAiB,CACxBC,GAA8C,EAC9CC,GAAwB,EACxBC,IAAyB,EACzB;EACA,IAAI,CAACF,GAAG,CAACG,OAAO,EAAE;IAChB,OAAOD,IAAI,CAAC,IAAIE,KAAK,CAAC,sBAAsB,CAAC,CAAC;EAChD;EACA,MAAM;IAACC;EAAG,CAAC,GAAGC,IAAI,CAACC,KAAK,CAACP,GAAG,CAACG,OAAO,CAAC;EACrCK,kBAAM,CAACC,IAAI,CAAE,WAAUJ,GAAI,KAAI,CAAC;EAChC,IAAAK,gCAAoB,EAACL,GAAG,CAAC;EACzBJ,GAAG,CAACU,GAAG,CAAC,IAAI,CAAC;AACf;AAAC,eAEc,IAAAC,kBAAO,GAAE,CAACC,GAAG,CAACC,0BAAiB,CAAC,CAACD,GAAG,CAACd,iBAAiB,CAAC;AAAA"}

View File

@@ -0,0 +1,10 @@
/// <reference types="node" />
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import http from 'http';
export default function rawBodyMiddleware(req: http.IncomingMessage, _res: http.ServerResponse, next: (err?: any) => void): void;
//# sourceMappingURL=rawBodyMiddleware.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"rawBodyMiddleware.d.ts","sourceRoot":"","sources":["../src/rawBodyMiddleware.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACvC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,IAAI,EAAE,IAAI,CAAC,cAAc,EACzB,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,QAY1B"}

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = rawBodyMiddleware;
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function rawBodyMiddleware(req, _res, next) {
req.rawBody = '';
req.setEncoding('utf8');
req.on('data', chunk => {
req.rawBody += chunk;
});
req.on('end', () => {
next();
});
}
//# sourceMappingURL=rawBodyMiddleware.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["rawBodyMiddleware","req","_res","next","rawBody","setEncoding","on","chunk"],"sources":["../src/rawBodyMiddleware.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport http from 'http';\n\nexport default function rawBodyMiddleware(\n req: http.IncomingMessage,\n _res: http.ServerResponse,\n next: (err?: any) => void,\n) {\n (req as http.IncomingMessage & {rawBody: string}).rawBody = '';\n req.setEncoding('utf8');\n\n req.on('data', (chunk: string) => {\n (req as http.IncomingMessage & {rawBody: string}).rawBody += chunk;\n });\n\n req.on('end', () => {\n next();\n });\n}\n"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;;AAGe,SAASA,iBAAiB,CACvCC,GAAyB,EACzBC,IAAyB,EACzBC,IAAyB,EACzB;EACCF,GAAG,CAA8CG,OAAO,GAAG,EAAE;EAC9DH,GAAG,CAACI,WAAW,CAAC,MAAM,CAAC;EAEvBJ,GAAG,CAACK,EAAE,CAAC,MAAM,EAAGC,KAAa,IAAK;IAC/BN,GAAG,CAA8CG,OAAO,IAAIG,KAAK;EACpE,CAAC,CAAC;EAEFN,GAAG,CAACK,EAAE,CAAC,KAAK,EAAE,MAAM;IAClBH,IAAI,EAAE;EACR,CAAC,CAAC;AACJ"}

View File

@@ -0,0 +1,10 @@
/// <reference types="node" />
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import http from 'http';
export default function securityHeadersMiddleware(req: http.IncomingMessage, res: http.ServerResponse, next: (err?: any) => void): void;
//# sourceMappingURL=securityHeadersMiddleware.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"securityHeadersMiddleware.d.ts","sourceRoot":"","sources":["../src/securityHeadersMiddleware.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,IAAI,QAsB1B"}

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = securityHeadersMiddleware;
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function securityHeadersMiddleware(req, res, next) {
// Block any cross origin request.
if (typeof req.headers.origin === 'string' && !req.headers.origin.match(/^https?:\/\/localhost:/) && !req.headers.origin.startsWith('devtools://devtools')) {
next(new Error('Unauthorized request from ' + req.headers.origin + '. This may happen because of a conflicting browser extension. Please try to disable it and try again.'));
return;
}
// Block MIME-type sniffing.
res.setHeader('X-Content-Type-Options', 'nosniff');
next();
}
//# sourceMappingURL=securityHeadersMiddleware.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["securityHeadersMiddleware","req","res","next","headers","origin","match","startsWith","Error","setHeader"],"sources":["../src/securityHeadersMiddleware.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport http from 'http';\n\nexport default function securityHeadersMiddleware(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n next: (err?: any) => void,\n) {\n // Block any cross origin request.\n if (\n typeof req.headers.origin === 'string' &&\n !req.headers.origin.match(/^https?:\\/\\/localhost:/) &&\n !req.headers.origin.startsWith('devtools://devtools')\n ) {\n next(\n new Error(\n 'Unauthorized request from ' +\n req.headers.origin +\n '. This may happen because of a conflicting browser extension. Please try to disable it and try again.',\n ),\n );\n return;\n }\n\n // Block MIME-type sniffing.\n res.setHeader('X-Content-Type-Options', 'nosniff');\n\n next();\n}\n"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;;AAGe,SAASA,yBAAyB,CAC/CC,GAAyB,EACzBC,GAAwB,EACxBC,IAAyB,EACzB;EACA;EACA,IACE,OAAOF,GAAG,CAACG,OAAO,CAACC,MAAM,KAAK,QAAQ,IACtC,CAACJ,GAAG,CAACG,OAAO,CAACC,MAAM,CAACC,KAAK,CAAC,wBAAwB,CAAC,IACnD,CAACL,GAAG,CAACG,OAAO,CAACC,MAAM,CAACE,UAAU,CAAC,qBAAqB,CAAC,EACrD;IACAJ,IAAI,CACF,IAAIK,KAAK,CACP,4BAA4B,GAC1BP,GAAG,CAACG,OAAO,CAACC,MAAM,GAClB,uGAAuG,CAC1G,CACF;IACD;EACF;;EAEA;EACAH,GAAG,CAACO,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC;EAElDN,IAAI,EAAE;AACR"}

View File

@@ -0,0 +1,14 @@
/// <reference types="node" />
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import http from 'http';
/**
* Status page so that anyone who needs to can verify that the packager is
* running on 8081 and not another program / service.
*/
export default function statusPageMiddleware(_req: http.IncomingMessage, res: http.ServerResponse): void;
//# sourceMappingURL=statusPageMiddleware.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"statusPageMiddleware.d.ts","sourceRoot":"","sources":["../src/statusPageMiddleware.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAC1C,IAAI,EAAE,IAAI,CAAC,eAAe,EAC1B,GAAG,EAAE,IAAI,CAAC,cAAc,QAIzB"}

View File

@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = statusPageMiddleware;
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/**
* Status page so that anyone who needs to can verify that the packager is
* running on 8081 and not another program / service.
*/
function statusPageMiddleware(_req, res) {
res.setHeader('X-React-Native-Project-Root', process.cwd());
res.end('packager-status:running');
}
//# sourceMappingURL=statusPageMiddleware.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["statusPageMiddleware","_req","res","setHeader","process","cwd","end"],"sources":["../src/statusPageMiddleware.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport http from 'http';\n\n/**\n * Status page so that anyone who needs to can verify that the packager is\n * running on 8081 and not another program / service.\n */\nexport default function statusPageMiddleware(\n _req: http.IncomingMessage,\n res: http.ServerResponse,\n) {\n res.setHeader('X-React-Native-Project-Root', process.cwd());\n res.end('packager-status:running');\n}\n"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACe,SAASA,oBAAoB,CAC1CC,IAA0B,EAC1BC,GAAwB,EACxB;EACAA,GAAG,CAACC,SAAS,CAAC,6BAA6B,EAAEC,OAAO,CAACC,GAAG,EAAE,CAAC;EAC3DH,GAAG,CAACI,GAAG,CAAC,yBAAyB,CAAC;AACpC"}

View File

@@ -0,0 +1,12 @@
/// <reference types="node" />
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import http from 'http';
export default function systraceProfileMiddleware(req: http.IncomingMessage & {
rawBody: string;
}, res: http.ServerResponse): void;
//# sourceMappingURL=systraceProfileMiddleware.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"systraceProfileMiddleware.d.ts","sourceRoot":"","sources":["../src/systraceProfileMiddleware.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;AACH,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,GAAG,EAAE,IAAI,CAAC,eAAe,GAAG;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,EAC7C,GAAG,EAAE,IAAI,CAAC,cAAc,QAYzB"}

View File

@@ -0,0 +1,38 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = systraceProfileMiddleware;
function _fs() {
const data = _interopRequireDefault(require("fs"));
_fs = function () {
return data;
};
return data;
}
function _cliTools() {
const data = require("@react-native-community/cli-tools");
_cliTools = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
function systraceProfileMiddleware(req, res) {
_cliTools().logger.info('Dumping profile information...');
const dumpName = `/tmp/dump_${Date.now()}.json`;
_fs().default.writeFileSync(dumpName, req.rawBody);
const response = `Your profile was saved at:\n${dumpName}\n\n` + 'On Google Chrome navigate to chrome://tracing and then click on "load" ' + 'to load and visualise your profile.\n\n' + 'This message is also printed to your console by the packager so you can copy it :)';
_cliTools().logger.info(response);
res.end(response);
}
//# sourceMappingURL=systraceProfileMiddleware.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["systraceProfileMiddleware","req","res","logger","info","dumpName","Date","now","fs","writeFileSync","rawBody","response","end"],"sources":["../src/systraceProfileMiddleware.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nimport http from 'http';\nimport fs from 'fs';\nimport {logger} from '@react-native-community/cli-tools';\n\nexport default function systraceProfileMiddleware(\n req: http.IncomingMessage & {rawBody: string},\n res: http.ServerResponse,\n) {\n logger.info('Dumping profile information...');\n const dumpName = `/tmp/dump_${Date.now()}.json`;\n fs.writeFileSync(dumpName, req.rawBody);\n const response =\n `Your profile was saved at:\\n${dumpName}\\n\\n` +\n 'On Google Chrome navigate to chrome://tracing and then click on \"load\" ' +\n 'to load and visualise your profile.\\n\\n' +\n 'This message is also printed to your console by the packager so you can copy it :)';\n logger.info(response);\n res.end(response);\n}\n"],"mappings":";;;;;;AAOA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AACA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AAAyD;AARzD;AACA;AACA;AACA;AACA;AACA;;AAKe,SAASA,yBAAyB,CAC/CC,GAA6C,EAC7CC,GAAwB,EACxB;EACAC,kBAAM,CAACC,IAAI,CAAC,gCAAgC,CAAC;EAC7C,MAAMC,QAAQ,GAAI,aAAYC,IAAI,CAACC,GAAG,EAAG,OAAM;EAC/CC,aAAE,CAACC,aAAa,CAACJ,QAAQ,EAAEJ,GAAG,CAACS,OAAO,CAAC;EACvC,MAAMC,QAAQ,GACX,+BAA8BN,QAAS,MAAK,GAC7C,yEAAyE,GACzE,yCAAyC,GACzC,oFAAoF;EACtFF,kBAAM,CAACC,IAAI,CAACO,QAAQ,CAAC;EACrBT,GAAG,CAACU,GAAG,CAACD,QAAQ,CAAC;AACnB"}

View File

@@ -0,0 +1,14 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import ws from 'ws';
export default function createDebuggerProxyEndpoint(): {
server: ws.Server;
isDebuggerConnected: () => boolean;
};
//# sourceMappingURL=createDebuggerProxyEndpoint.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"createDebuggerProxyEndpoint.d.ts","sourceRoot":"","sources":["../../src/websocket/createDebuggerProxyEndpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB,MAAM,CAAC,OAAO,UAAU,2BAA2B,IAAI;IACrD,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,OAAO,CAAC;CACpC,CAsEA"}

View File

@@ -0,0 +1,104 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = createDebuggerProxyEndpoint;
function _ws() {
const data = _interopRequireDefault(require("ws"));
_ws = function () {
return data;
};
return data;
}
function _cliTools() {
const data = require("@react-native-community/cli-tools");
_cliTools = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
function createDebuggerProxyEndpoint() {
const WebSocketServer = _ws().default.Server;
const wss = new WebSocketServer({
noServer: true
});
let debuggerSocket;
let clientSocket;
function send(dest, message) {
if (!dest) {
return;
}
try {
dest.send(message);
} catch (e) {
_cliTools().logger.warn(e);
// Sometimes this call throws 'not opened'
}
}
const debuggerSocketCloseHandler = () => {
debuggerSocket = null;
if (clientSocket) {
clientSocket.close(1011, 'Debugger was disconnected');
}
};
const clientSocketCloseHandler = () => {
clientSocket = null;
send(debuggerSocket, JSON.stringify({
method: '$disconnected'
}));
};
wss.on('connection', (socket, request) => {
const {
url
} = request;
if (url && url.indexOf('role=debugger') > -1) {
if (debuggerSocket) {
socket.close(1011, 'Another debugger is already connected');
return;
}
debuggerSocket = socket;
if (debuggerSocket) {
debuggerSocket.onerror = debuggerSocketCloseHandler;
debuggerSocket.onclose = debuggerSocketCloseHandler;
debuggerSocket.onmessage = ({
data
}) => send(clientSocket, data);
}
} else if (url && url.indexOf('role=client') > -1) {
if (clientSocket) {
clientSocket.onerror = () => {};
clientSocket.onclose = () => {};
clientSocket.onmessage = () => {};
clientSocket.close(1011, 'Another client connected');
}
clientSocket = socket;
clientSocket.onerror = clientSocketCloseHandler;
clientSocket.onclose = clientSocketCloseHandler;
clientSocket.onmessage = ({
data
}) => send(debuggerSocket, data);
} else {
socket.close(1011, 'Missing role param');
}
});
return {
server: wss,
isDebuggerConnected() {
return !!debuggerSocket;
}
};
}
//# sourceMappingURL=createDebuggerProxyEndpoint.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"names":["createDebuggerProxyEndpoint","WebSocketServer","ws","Server","wss","noServer","debuggerSocket","clientSocket","send","dest","message","e","logger","warn","debuggerSocketCloseHandler","close","clientSocketCloseHandler","JSON","stringify","method","on","socket","request","url","indexOf","onerror","onclose","onmessage","data","server","isDebuggerConnected"],"sources":["../../src/websocket/createDebuggerProxyEndpoint.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * @format\n */\n\nimport ws from 'ws';\nimport {logger} from '@react-native-community/cli-tools';\n\nexport default function createDebuggerProxyEndpoint(): {\n server: ws.Server;\n isDebuggerConnected: () => boolean;\n} {\n const WebSocketServer = ws.Server;\n const wss = new WebSocketServer({\n noServer: true,\n });\n\n let debuggerSocket: ws | null;\n let clientSocket: ws | null;\n\n function send(dest: ws | null, message: ws.Data) {\n if (!dest) {\n return;\n }\n\n try {\n dest.send(message);\n } catch (e) {\n logger.warn(e as any);\n // Sometimes this call throws 'not opened'\n }\n }\n\n const debuggerSocketCloseHandler = () => {\n debuggerSocket = null;\n if (clientSocket) {\n clientSocket.close(1011, 'Debugger was disconnected');\n }\n };\n\n const clientSocketCloseHandler = () => {\n clientSocket = null;\n send(debuggerSocket, JSON.stringify({method: '$disconnected'}));\n };\n\n wss.on('connection', (socket, request) => {\n const {url} = request;\n\n if (url && url.indexOf('role=debugger') > -1) {\n if (debuggerSocket) {\n socket.close(1011, 'Another debugger is already connected');\n return;\n }\n debuggerSocket = socket;\n if (debuggerSocket) {\n debuggerSocket.onerror = debuggerSocketCloseHandler;\n debuggerSocket.onclose = debuggerSocketCloseHandler;\n debuggerSocket.onmessage = ({data}) => send(clientSocket, data);\n }\n } else if (url && url.indexOf('role=client') > -1) {\n if (clientSocket) {\n clientSocket.onerror = () => {};\n clientSocket.onclose = () => {};\n clientSocket.onmessage = () => {};\n clientSocket.close(1011, 'Another client connected');\n }\n clientSocket = socket;\n clientSocket.onerror = clientSocketCloseHandler;\n clientSocket.onclose = clientSocketCloseHandler;\n clientSocket.onmessage = ({data}) => send(debuggerSocket, data);\n } else {\n socket.close(1011, 'Missing role param');\n }\n });\n\n return {\n server: wss,\n isDebuggerConnected() {\n return !!debuggerSocket;\n },\n };\n}\n"],"mappings":";;;;;;AASA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AACA;EAAA;EAAA;IAAA;EAAA;EAAA;AAAA;AAAyD;AAVzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAKe,SAASA,2BAA2B,GAGjD;EACA,MAAMC,eAAe,GAAGC,aAAE,CAACC,MAAM;EACjC,MAAMC,GAAG,GAAG,IAAIH,eAAe,CAAC;IAC9BI,QAAQ,EAAE;EACZ,CAAC,CAAC;EAEF,IAAIC,cAAyB;EAC7B,IAAIC,YAAuB;EAE3B,SAASC,IAAI,CAACC,IAAe,EAAEC,OAAgB,EAAE;IAC/C,IAAI,CAACD,IAAI,EAAE;MACT;IACF;IAEA,IAAI;MACFA,IAAI,CAACD,IAAI,CAACE,OAAO,CAAC;IACpB,CAAC,CAAC,OAAOC,CAAC,EAAE;MACVC,kBAAM,CAACC,IAAI,CAACF,CAAC,CAAQ;MACrB;IACF;EACF;;EAEA,MAAMG,0BAA0B,GAAG,MAAM;IACvCR,cAAc,GAAG,IAAI;IACrB,IAAIC,YAAY,EAAE;MAChBA,YAAY,CAACQ,KAAK,CAAC,IAAI,EAAE,2BAA2B,CAAC;IACvD;EACF,CAAC;EAED,MAAMC,wBAAwB,GAAG,MAAM;IACrCT,YAAY,GAAG,IAAI;IACnBC,IAAI,CAACF,cAAc,EAAEW,IAAI,CAACC,SAAS,CAAC;MAACC,MAAM,EAAE;IAAe,CAAC,CAAC,CAAC;EACjE,CAAC;EAEDf,GAAG,CAACgB,EAAE,CAAC,YAAY,EAAE,CAACC,MAAM,EAAEC,OAAO,KAAK;IACxC,MAAM;MAACC;IAAG,CAAC,GAAGD,OAAO;IAErB,IAAIC,GAAG,IAAIA,GAAG,CAACC,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,EAAE;MAC5C,IAAIlB,cAAc,EAAE;QAClBe,MAAM,CAACN,KAAK,CAAC,IAAI,EAAE,uCAAuC,CAAC;QAC3D;MACF;MACAT,cAAc,GAAGe,MAAM;MACvB,IAAIf,cAAc,EAAE;QAClBA,cAAc,CAACmB,OAAO,GAAGX,0BAA0B;QACnDR,cAAc,CAACoB,OAAO,GAAGZ,0BAA0B;QACnDR,cAAc,CAACqB,SAAS,GAAG,CAAC;UAACC;QAAI,CAAC,KAAKpB,IAAI,CAACD,YAAY,EAAEqB,IAAI,CAAC;MACjE;IACF,CAAC,MAAM,IAAIL,GAAG,IAAIA,GAAG,CAACC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE;MACjD,IAAIjB,YAAY,EAAE;QAChBA,YAAY,CAACkB,OAAO,GAAG,MAAM,CAAC,CAAC;QAC/BlB,YAAY,CAACmB,OAAO,GAAG,MAAM,CAAC,CAAC;QAC/BnB,YAAY,CAACoB,SAAS,GAAG,MAAM,CAAC,CAAC;QACjCpB,YAAY,CAACQ,KAAK,CAAC,IAAI,EAAE,0BAA0B,CAAC;MACtD;MACAR,YAAY,GAAGc,MAAM;MACrBd,YAAY,CAACkB,OAAO,GAAGT,wBAAwB;MAC/CT,YAAY,CAACmB,OAAO,GAAGV,wBAAwB;MAC/CT,YAAY,CAACoB,SAAS,GAAG,CAAC;QAACC;MAAI,CAAC,KAAKpB,IAAI,CAACF,cAAc,EAAEsB,IAAI,CAAC;IACjE,CAAC,MAAM;MACLP,MAAM,CAACN,KAAK,CAAC,IAAI,EAAE,oBAAoB,CAAC;IAC1C;EACF,CAAC,CAAC;EAEF,OAAO;IACLc,MAAM,EAAEzB,GAAG;IACX0B,mBAAmB,GAAG;MACpB,OAAO,CAAC,CAACxB,cAAc;IACzB;EACF,CAAC;AACH"}

View File

@@ -0,0 +1,10 @@
import { Server as WebSocketServer } from 'ws';
/**
* Starts the eventsSocket at the given path
*
*/
export default function createEventsSocketEndpoint(broadcast: (method: string, params?: Record<string, any>) => void): {
server: WebSocketServer;
reportEvent: (event: any) => void;
};
//# sourceMappingURL=createEventsSocketEndpoint.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"createEventsSocketEndpoint.d.ts","sourceRoot":"","sources":["../../src/websocket/createEventsSocketEndpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,IAAI,eAAe,EAAC,MAAM,IAAI,CAAC;AAsG7C;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAChD,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,GAChE;IACD,MAAM,EAAE,eAAe,CAAC;IACxB,WAAW,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CACnC,CAqFA"}

View File

@@ -0,0 +1,192 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = createEventsSocketEndpoint;
function _ws() {
const data = require("ws");
_ws = function () {
return data;
};
return data;
}
function _cliTools() {
const data = require("@react-native-community/cli-tools");
_cliTools = function () {
return data;
};
return data;
}
function _prettyFormat() {
const data = _interopRequireDefault(require("pretty-format"));
_prettyFormat = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The eventsSocket websocket listens at the 'events/` for websocket
* connections, on which all Metro reports will be emitted.
*
* This is mostly useful for developer tools (clients) that wants to monitor Metro,
* and the apps connected to Metro.
*
* The eventsSocket provides the following features:
* - it reports any Metro event (that is reported through a reporter) to all clients
* - it reports any console.log's (and friends) from the connected app to all clients
* (as client_log event)
* - it allows connected clients to send commands through Metro to the connected app.
* This reuses the generic command mechanism.
* Two useful commands are 'reload' and 'devmenu'.
*/
/**
* This number is used to version the communication protocol between
* Dev tooling like Flipper and Metro, so that in the future we can recognize
* messages coming from old clients, so that it will be simpler to implement
* backward compatibility.
*
* We start at 2 as the protocol is currently the same as used internally at FB,
* which happens to be at version 2 as well.
*/
const PROTOCOL_VERSION = 2;
function parseMessage(data) {
try {
const message = JSON.parse(data);
if (message.version === PROTOCOL_VERSION) {
return message;
}
_cliTools().logger.error('Received message had wrong protocol version: ' + message.version);
} catch {
_cliTools().logger.error('Failed to parse the message as JSON:\n' + data);
}
return undefined;
}
/**
* Two types of messages will arrive in this function,
* 1) messages generated by Metro itself (through the reporter abstraction)
* those are yet to be serialized, and can contain any kind of data structure
* 2) a specific event generated by Metro is `client_log`, which describes
* console.* calls in the app.
* The arguments send to the console are pretty printed so that they can be
* displayed in a nicer way in dev tools
*
* @param message
*/
function serializeMessage(message) {
// We do want to send Metro report messages, but their contents is not guaranteed to be serializable.
// For some known types we will pretty print otherwise not serializable parts first:
let toSerialize = message;
if (message && message.error && message.error instanceof Error) {
toSerialize = {
...message,
error: (0, _prettyFormat().default)(message.error, {
escapeString: true,
highlight: true,
maxDepth: 3,
min: true
})
};
} else if (message && message.type === 'client_log') {
toSerialize = {
...message,
data: message.data.map(item => typeof item === 'string' ? item : (0, _prettyFormat().default)(item, {
escapeString: true,
highlight: true,
maxDepth: 3,
min: true,
plugins: [_prettyFormat().default.plugins.ReactElement]
}))
};
}
try {
return JSON.stringify(toSerialize);
} catch (e) {
_cliTools().logger.error('Failed to serialize: ' + e);
return null;
}
}
/**
* Starts the eventsSocket at the given path
*
*/
function createEventsSocketEndpoint(broadcast) {
const wss = new (_ws().Server)({
noServer: true,
verifyClient({
origin
}) {
// This exposes the full JS logs and enables issuing commands like reload
// so let's make sure only locally running stuff can connect to it
// origin is only checked if it is set, e.g. when the request is made from a (CORS) browser
// any 'back-end' connection isn't CORS at all, and has full control over the origin header,
// so there is no point in checking it security wise
return !origin || origin.startsWith('http://localhost:') || origin.startsWith('file:');
}
});
const clients = new Map();
let nextClientId = 0;
/**
* broadCastEvent is called by reportEvent (below), which is called by the
* default reporter of this server, to make sure that all Metro events are
* broadcasted to all connected clients
* (that is, all devtools such as Flipper, _not_: connected apps)
*
* @param message
*/
function broadCastEvent(message) {
if (!clients.size) {
return;
}
const serialized = serializeMessage(message);
if (!serialized) {
return;
}
for (const ws of clients.values()) {
try {
ws.send(serialized);
} catch (e) {
_cliTools().logger.error(`Failed to send broadcast to client due to:\n ${e.toString()}`);
}
}
}
wss.on('connection', function (clientWs) {
const clientId = `client#${nextClientId++}`;
clients.set(clientId, clientWs);
clientWs.onclose = clientWs.onerror = () => {
clients.delete(clientId);
};
clientWs.onmessage = event => {
const message = parseMessage(event.data.toString());
if (message == null) {
return;
}
if (message.type === 'command') {
try {
/**
* messageSocket.broadcast (not to be confused with our own broadcast above)
* forwards a command to all connected React Native applications.
*/
broadcast(message.command, message.params);
} catch (e) {
_cliTools().logger.error('Failed to forward message to clients: ', e);
}
} else {
_cliTools().logger.error('Unknown message type: ', message.type);
}
};
});
return {
server: wss,
reportEvent: event => {
broadCastEvent(event);
}
};
}
//# sourceMappingURL=createEventsSocketEndpoint.ts.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { Server as WebSocketServer } from 'ws';
export default function createMessageSocketEndpoint(): {
server: WebSocketServer;
broadcast: (method: string, params?: Record<string, any>) => void;
};
//# sourceMappingURL=createMessageSocketEndpoint.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"createMessageSocketEndpoint.d.ts","sourceRoot":"","sources":["../../src/websocket/createMessageSocketEndpoint.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAC,MAAM,IAAI,eAAe,EAAC,MAAM,IAAI,CAAC;AA8D7C,MAAM,CAAC,OAAO,UAAU,2BAA2B,IAAI;IACrD,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;CACnE,CAiLA"}

View File

@@ -0,0 +1,207 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = createMessageSocketEndpoint;
function _url() {
const data = _interopRequireDefault(require("url"));
_url = function () {
return data;
};
return data;
}
function _ws() {
const data = require("ws");
_ws = function () {
return data;
};
return data;
}
function _cliTools() {
const data = require("@react-native-community/cli-tools");
_cliTools = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
const PROTOCOL_VERSION = 2;
function parseMessage(data, binary) {
if (binary) {
_cliTools().logger.error('Expected text message, got binary!');
return undefined;
}
try {
const message = JSON.parse(data);
if (message.version === PROTOCOL_VERSION) {
return message;
}
_cliTools().logger.error(`Received message had wrong protocol version: ${message.version}`);
} catch (e) {
_cliTools().logger.error(`Failed to parse the message as JSON:\n${data}`);
}
return undefined;
}
function isBroadcast(message) {
return typeof message.method === 'string' && message.id === undefined && message.target === undefined;
}
function isRequest(message) {
return typeof message.method === 'string' && typeof message.target === 'string';
}
function isResponse(message) {
return typeof message.id === 'object' && typeof message.id.requestId !== 'undefined' && typeof message.id.clientId === 'string' && (message.result !== undefined || message.error !== undefined);
}
function createMessageSocketEndpoint() {
const wss = new (_ws().Server)({
noServer: true
});
const clients = new Map();
let nextClientId = 0;
function getClientWs(clientId) {
const clientWs = clients.get(clientId);
if (clientWs === undefined) {
throw new Error(`could not find id "${clientId}" while forwarding request`);
}
return clientWs;
}
function handleSendBroadcast(broadcasterId, message) {
const forwarded = {
version: PROTOCOL_VERSION,
method: message.method,
params: message.params
};
if (clients.size === 0) {
_cliTools().logger.warn(`No apps connected. Sending "${message.method}" to all React Native apps failed. Make sure your app is running in the simulator or on a phone connected via USB.`);
}
for (const [otherId, otherWs] of clients) {
if (otherId !== broadcasterId) {
try {
otherWs.send(JSON.stringify(forwarded));
} catch (e) {
_cliTools().logger.error(`Failed to send broadcast to client: '${otherId}' ` + `due to:\n ${e.toString()}`);
}
}
}
}
wss.on('connection', clientWs => {
const clientId = `client#${nextClientId++}`;
function handleCaughtError(message, error) {
const errorMessage = {
id: message.id,
method: message.method,
target: message.target,
error: message.error === undefined ? 'undefined' : 'defined',
params: message.params === undefined ? 'undefined' : 'defined',
result: message.result === undefined ? 'undefined' : 'defined'
};
if (message.id === undefined) {
_cliTools().logger.error(`Handling message from ${clientId} failed with:\n${error}\n` + `message:\n${JSON.stringify(errorMessage)}`);
} else {
try {
clientWs.send(JSON.stringify({
version: PROTOCOL_VERSION,
error,
id: message.id
}));
} catch (e) {
_cliTools().logger.error(`Failed to reply to ${clientId} with error:\n${error}` + `\nmessage:\n${JSON.stringify(errorMessage)}` + `\ndue to error: ${e.toString()}`);
}
}
}
function handleServerRequest(message) {
let result = null;
switch (message.method) {
case 'getid':
result = clientId;
break;
case 'getpeers':
result = {};
clients.forEach((otherWs, otherId) => {
if (clientId !== otherId) {
result[otherId] = _url().default.parse(otherWs.upgradeReq.url, true).query;
}
});
break;
default:
throw new Error(`unknown method: ${message.method}`);
}
clientWs.send(JSON.stringify({
version: PROTOCOL_VERSION,
result,
id: message.id
}));
}
function forwardRequest(message) {
getClientWs(message.target).send(JSON.stringify({
version: PROTOCOL_VERSION,
method: message.method,
params: message.params,
id: message.id === undefined ? undefined : {
requestId: message.id,
clientId
}
}));
}
function forwardResponse(message) {
if (!message.id) {
return;
}
getClientWs(message.id.clientId).send(JSON.stringify({
version: PROTOCOL_VERSION,
result: message.result,
error: message.error,
id: message.id.requestId
}));
}
clients.set(clientId, clientWs);
const onCloseHandler = () => {
clientWs.onmessage = () => {};
clients.delete(clientId);
};
clientWs.onclose = onCloseHandler;
clientWs.onerror = onCloseHandler;
clientWs.onmessage = event => {
const message = parseMessage(event.data, event.binary);
if (message === undefined) {
_cliTools().logger.error('Received message not matching protocol');
return;
}
try {
if (isBroadcast(message)) {
handleSendBroadcast(clientId, message);
} else if (isRequest(message)) {
if (message.target === 'server') {
handleServerRequest(message);
} else {
forwardRequest(message);
}
} else if (isResponse(message)) {
forwardResponse(message);
} else {
throw new Error('Invalid message, did not match the protocol');
}
} catch (e) {
handleCaughtError(message, e.toString());
}
};
});
return {
server: wss,
broadcast: (method, params) => {
handleSendBroadcast(null, {
method,
params
});
}
};
}
//# sourceMappingURL=createMessageSocketEndpoint.ts.map

File diff suppressed because one or more lines are too long