diff --git a/.changeset/weak-candles-dream.md b/.changeset/weak-candles-dream.md new file mode 100644 index 000000000..a74c97f86 --- /dev/null +++ b/.changeset/weak-candles-dream.md @@ -0,0 +1,6 @@ +--- +"@callstack/repack-dev-server": patch +"@callstack/repack": patch +--- + +Drop dependency on `@react-native-community/cli-server-api` in the DevServer diff --git a/packages/dev-server/package.json b/packages/dev-server/package.json index 9761dd00b..3400d2803 100644 --- a/packages/dev-server/package.json +++ b/packages/dev-server/package.json @@ -35,6 +35,8 @@ "fastify": "^4.24.3", "fastify-favicon": "^4.3.0", "fastify-plugin": "^4.5.1", + "launch-editor": "^2.10.0", + "open": "^10.1.0", "pretty-format": "^28.1.0", "source-map": "^0.7.4", "ws": "^8.7.0" @@ -42,19 +44,10 @@ "devDependencies": { "@babel/cli": "^7.23.9", "@babel/core": "^7.23.9", - "@react-native-community/cli-server-api": "15.0.1", "@types/babel__code-frame": "^7.0.3", "@types/node": "catalog:", "@types/ws": "^8.5.3", "babel-plugin-add-import-extension": "^1.6.0", "typescript": "catalog:" - }, - "peerDependencies": { - "@react-native-community/cli-server-api": ">=13.6.4" - }, - "peerDependenciesMeta": { - "@react-native-community/cli-server-api": { - "optional": true - } } } diff --git a/packages/dev-server/src/plugins/devtools/devtoolsPlugin.ts b/packages/dev-server/src/plugins/devtools/devtoolsPlugin.ts index 26f540c74..5644a46e1 100644 --- a/packages/dev-server/src/plugins/devtools/devtoolsPlugin.ts +++ b/packages/dev-server/src/plugins/devtools/devtoolsPlugin.ts @@ -1,22 +1,50 @@ -import { - openStackFrameInEditorMiddleware, - openURLMiddleware, -} from '@react-native-community/cli-server-api'; import type { FastifyInstance } from 'fastify'; import fastifyPlugin from 'fastify-plugin'; +import launchEditor from 'launch-editor'; +import open from 'open'; -async function devtoolsPlugin( - instance: FastifyInstance, - { rootDir }: { rootDir: string } -) { - instance.use('/open-url', openURLMiddleware); +interface OpenURLRequestBody { + url: string; +} + +interface OpenStackFrameRequestBody { + file: string; + lineNumber: number; +} + +function parseRequestBody(body: unknown): T { + if (typeof body === 'object') return body as T; + if (typeof body === 'string') return JSON.parse(body) as T; + throw new Error(`Unsupported body type: ${typeof body}`); +} + +async function devtoolsPlugin(instance: FastifyInstance) { + // reference implementation in `@react-native-community/cli-server-api`: + // https://github.com/react-native-community/cli/blob/46436a12478464752999d34ed86adf3212348007/packages/cli-server-api/src/openURLMiddleware.ts + instance.route({ + method: ['POST'], + url: '/open-url', + handler: async (request, reply) => { + const { url } = parseRequestBody(request.body); + await open(url); + reply.send('OK'); + }, + }); - instance.use( - '/open-stack-frame', - openStackFrameInEditorMiddleware({ - watchFolders: [rootDir], - }) - ); + // reference implementation in `@react-native-community/cli-server-api`: + // https://github.com/react-native-community/cli/blob/46436a12478464752999d34ed86adf3212348007/packages/cli-server-api/src/openStackFrameMiddleware.ts + instance.route({ + method: ['POST'], + url: '/open-stack-frame', + handler: async (request, reply) => { + const { file, lineNumber } = parseRequestBody( + request.body + ); + // TODO fix rewriting of `webpack://` to rootDir of the project + launchEditor(`${file}:${lineNumber}`, process.env.REACT_EDITOR); + reply.send('OK'); + }, + }); instance.route({ method: ['GET', 'POST', 'PUT'], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 419c5a355..9fc526b8c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -372,6 +372,12 @@ importers: fastify-plugin: specifier: ^4.5.1 version: 4.5.1 + launch-editor: + specifier: ^2.10.0 + version: 2.10.0 + open: + specifier: ^10.1.0 + version: 10.1.0 pretty-format: specifier: ^28.1.0 version: 28.1.3 @@ -388,9 +394,6 @@ importers: '@babel/core': specifier: ^7.23.9 version: 7.25.2 - '@react-native-community/cli-server-api': - specifier: 15.0.1 - version: 15.0.1 '@types/babel__code-frame': specifier: ^7.0.3 version: 7.0.6 @@ -3495,6 +3498,10 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + bytes@3.0.0: resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} engines: {node: '>= 0.8'} @@ -3954,6 +3961,14 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} @@ -3965,6 +3980,10 @@ packages: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -4899,6 +4918,11 @@ packages: engines: {node: '>=8'} hasBin: true + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} @@ -4938,6 +4962,11 @@ packages: engines: {node: '>=18'} hasBin: true + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} @@ -4997,6 +5026,10 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -5296,6 +5329,9 @@ packages: resolution: {integrity: sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==} engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} + launch-editor@2.10.0: + resolution: {integrity: sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==} + leac@0.6.0: resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==} @@ -6102,6 +6138,10 @@ packages: only@0.0.2: resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==} + open@10.1.0: + resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} + engines: {node: '>=18'} + open@6.4.0: resolution: {integrity: sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==} engines: {node: '>=8'} @@ -6837,6 +6877,10 @@ packages: resolution: {integrity: sha512-iCuWH13x3XugYA73fW1Po2JLH/+zKRy+qoJc7GGkAhLVIIXF+Ldng0kEmtGPQ9MYDe129977rTQYeJzqHOSJ3w==} hasBin: true + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -11545,6 +11589,10 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + bytes@3.0.0: {} bytes@3.1.2: {} @@ -11968,6 +12016,13 @@ snapshots: deepmerge@4.3.1: {} + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + defaults@1.0.4: dependencies: clone: 1.0.4 @@ -11980,6 +12035,8 @@ snapshots: define-lazy-prop@2.0.0: {} + define-lazy-prop@3.0.0: {} + delayed-stream@1.0.0: {} delegates@1.0.0: {} @@ -12999,6 +13056,8 @@ snapshots: is-docker@2.2.1: {} + is-docker@3.0.0: {} + is-extendable@0.1.1: {} is-extglob@2.1.1: {} @@ -13023,6 +13082,10 @@ snapshots: is-in-ci@1.0.0: {} + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-interactive@1.0.0: {} is-number@7.0.0: {} @@ -13061,6 +13124,10 @@ snapshots: dependencies: is-docker: 2.2.1 + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + isarray@1.0.0: {} isexe@2.0.0: {} @@ -13591,6 +13658,11 @@ snapshots: transitivePeerDependencies: - supports-color + launch-editor@2.10.0: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.1 + leac@0.6.0: {} leven@3.1.0: {} @@ -14854,6 +14926,13 @@ snapshots: only@0.0.2: {} + open@10.1.0: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + open@6.4.0: dependencies: is-wsl: 1.1.0 @@ -15759,6 +15838,8 @@ snapshots: - supports-color - webpack + run-applescript@7.0.0: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3