@expo/cli 55.0.7 → 55.0.9

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 (69) hide show
  1. package/build/bin/cli +13 -1
  2. package/build/bin/cli.map +1 -1
  3. package/build/src/config/configAsync.js +1 -1
  4. package/build/src/config/configAsync.js.map +1 -1
  5. package/build/src/customize/customizeAsync.js +1 -1
  6. package/build/src/customize/customizeAsync.js.map +1 -1
  7. package/build/src/export/embed/exportEmbedAsync.js +1 -1
  8. package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
  9. package/build/src/export/exportApp.js +1 -1
  10. package/build/src/export/exportApp.js.map +1 -1
  11. package/build/src/export/exportStaticAsync.js +7 -11
  12. package/build/src/export/exportStaticAsync.js.map +1 -1
  13. package/build/src/export/web/exportWebAsync.js +1 -1
  14. package/build/src/export/web/exportWebAsync.js.map +1 -1
  15. package/build/src/install/installAsync.js +1 -1
  16. package/build/src/install/installAsync.js.map +1 -1
  17. package/build/src/lint/lintAsync.js +1 -1
  18. package/build/src/lint/lintAsync.js.map +1 -1
  19. package/build/src/prebuild/prebuildAsync.js +1 -1
  20. package/build/src/prebuild/prebuildAsync.js.map +1 -1
  21. package/build/src/run/android/runAndroidAsync.js +1 -1
  22. package/build/src/run/android/runAndroidAsync.js.map +1 -1
  23. package/build/src/run/ios/runIosAsync.js +1 -1
  24. package/build/src/run/ios/runIosAsync.js.map +1 -1
  25. package/build/src/serve/serveAsync.js +1 -1
  26. package/build/src/serve/serveAsync.js.map +1 -1
  27. package/build/src/start/interface/commandsTable.js +89 -69
  28. package/build/src/start/interface/commandsTable.js.map +1 -1
  29. package/build/src/start/interface/interactiveActions.js +29 -14
  30. package/build/src/start/interface/interactiveActions.js.map +1 -1
  31. package/build/src/start/server/BundlerDevServer.js +16 -9
  32. package/build/src/start/server/BundlerDevServer.js.map +1 -1
  33. package/build/src/start/server/DevServerManager.js +5 -1
  34. package/build/src/start/server/DevServerManager.js.map +1 -1
  35. package/build/src/start/server/UrlCreator.js +17 -7
  36. package/build/src/start/server/UrlCreator.js.map +1 -1
  37. package/build/src/start/server/getStaticRenderFunctions.js +8 -8
  38. package/build/src/start/server/getStaticRenderFunctions.js.map +1 -1
  39. package/build/src/start/server/metro/MetroBundlerDevServer.js +20 -20
  40. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  41. package/build/src/start/server/metro/MetroTerminalReporter.js +1 -1
  42. package/build/src/start/server/metro/MetroTerminalReporter.js.map +1 -1
  43. package/build/src/start/server/metro/createServerComponentsMiddleware.js +1 -1
  44. package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
  45. package/build/src/start/server/metro/dev-server/createMetroMiddleware.js +18 -18
  46. package/build/src/start/server/metro/dev-server/createMetroMiddleware.js.map +1 -1
  47. package/build/src/start/server/metro/log-box/LogBoxSymbolication.js +5 -1
  48. package/build/src/start/server/metro/log-box/LogBoxSymbolication.js.map +1 -1
  49. package/build/src/start/server/metro/resolveLoader.js +2 -0
  50. package/build/src/start/server/metro/resolveLoader.js.map +1 -1
  51. package/build/src/start/server/metro/runServer-fork.js +6 -5
  52. package/build/src/start/server/metro/runServer-fork.js.map +1 -1
  53. package/build/src/start/server/webpack/WebpackBundlerDevServer.js +4 -4
  54. package/build/src/start/server/webpack/WebpackBundlerDevServer.js.map +1 -1
  55. package/build/src/utils/editor.js +404 -31
  56. package/build/src/utils/editor.js.map +1 -1
  57. package/build/src/utils/getRunningProcess.js +80 -41
  58. package/build/src/utils/getRunningProcess.js.map +1 -1
  59. package/build/src/utils/ip.js +44 -8
  60. package/build/src/utils/ip.js.map +1 -1
  61. package/build/src/utils/nodeEnv.js +66 -1
  62. package/build/src/utils/nodeEnv.js.map +1 -1
  63. package/build/src/utils/port.js +2 -2
  64. package/build/src/utils/port.js.map +1 -1
  65. package/build/src/utils/qr.js +186 -0
  66. package/build/src/utils/qr.js.map +1 -0
  67. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  68. package/build/src/utils/telemetry/utils/context.js +1 -1
  69. package/package.json +16 -17
@@ -15,13 +15,16 @@ _export(exports, {
15
15
  getPID: function() {
16
16
  return getPID;
17
17
  },
18
+ getProcessCommand: function() {
19
+ return getProcessCommand;
20
+ },
18
21
  getRunningProcess: function() {
19
22
  return getRunningProcess;
20
23
  }
21
24
  });
22
- function _child_process() {
23
- const data = require("child_process");
24
- _child_process = function() {
25
+ function _spawnasync() {
26
+ const data = /*#__PURE__*/ _interop_require_default(require("@expo/spawn-async"));
27
+ _spawnasync = function() {
25
28
  return data;
26
29
  };
27
30
  return data;
@@ -33,6 +36,11 @@ function _path() {
33
36
  };
34
37
  return data;
35
38
  }
39
+ function _interop_require_default(obj) {
40
+ return obj && obj.__esModule ? obj : {
41
+ default: obj
42
+ };
43
+ }
36
44
  function _getRequireWildcardCache(nodeInterop) {
37
45
  if (typeof WeakMap !== "function") return null;
38
46
  var cacheBabelInterop = new WeakMap();
@@ -75,68 +83,99 @@ function _interop_require_wildcard(obj, nodeInterop) {
75
83
  return newObj;
76
84
  }
77
85
  const debug = require('debug')('expo:utils:getRunningProcess');
78
- const defaultOptions = {
79
- encoding: 'utf8',
80
- stdio: [
81
- 'pipe',
82
- 'pipe',
83
- 'ignore'
84
- ]
85
- };
86
- function getPID(port) {
86
+ /** Timeout applied to shell commands */ const timeout = 350;
87
+ async function getPID(port) {
87
88
  try {
88
- const results = (0, _child_process().execFileSync)('lsof', [
89
+ const { stdout } = await (0, _spawnasync().default)('lsof', [
89
90
  `-i:${port}`,
90
91
  '-P',
91
92
  '-t',
92
93
  '-sTCP:LISTEN'
93
- ], defaultOptions).split('\n')[0].trim();
94
- const pid = Number(results);
94
+ ], {
95
+ timeout
96
+ });
97
+ const pid = Number(stdout.split('\n', 1)[0].trim());
95
98
  debug(`pid: ${pid} for port: ${port}`);
96
- return pid;
99
+ return Number.isSafeInteger(pid) ? pid : null;
97
100
  } catch (error) {
98
101
  debug(`No pid found for port: ${port}. Error: ${error}`);
99
102
  return null;
100
103
  }
101
104
  }
102
105
  /** Get `package.json` `name` field for a given directory. Returns `null` if none exist. */ function getPackageName(packageRoot) {
103
- const packageJson = _path().join(packageRoot, 'package.json');
104
106
  try {
107
+ const packageJson = _path().resolve(packageRoot, 'package.json');
105
108
  return require(packageJson).name || null;
106
- } catch {
109
+ } catch (error) {
107
110
  return null;
108
111
  }
109
112
  }
110
- /** Returns a command like `node /Users/evanbacon/.../bin/expo start` or the package.json name. */ function getProcessCommand(pid, procDirectory) {
111
- const name = getPackageName(procDirectory);
112
- if (name) {
113
- return name;
113
+ async function getProcessCommand(pid, procDirectory) {
114
+ let name = getPackageName(procDirectory);
115
+ if (!name) {
116
+ // ps
117
+ // -o args=: Output argv without header
118
+ // -p [pid]: For process of PID
119
+ const { stdout } = await (0, _spawnasync().default)('ps', [
120
+ '-o',
121
+ 'args=',
122
+ '-p',
123
+ `${pid}`
124
+ ], {
125
+ timeout
126
+ });
127
+ name = stdout.trim();
114
128
  }
115
- return (0, _child_process().execSync)(`ps -o command -p ${pid} | sed -n 2p`, defaultOptions).replace(/\n$/, '').trim();
129
+ return name || null;
116
130
  }
117
- function getDirectoryOfProcessById(processId) {
118
- return (0, _child_process().execSync)(`lsof -p ${processId} | awk '$4=="cwd" {for (i=9; i<=NF; i++) printf "%s ", $i}'`, defaultOptions).trim();
131
+ async function getDirectoryOfProcessById(pid) {
132
+ try {
133
+ var _stdout_split_find;
134
+ // lsof
135
+ // -F n: ask for machine readable output
136
+ // -a: apply conditions as logical AND
137
+ // -d cwd: Filter by cwd fd
138
+ // -p [pid]: Filter by input process id
139
+ const { stdout } = await (0, _spawnasync().default)('lsof', [
140
+ '-F',
141
+ 'n',
142
+ '-a',
143
+ '-d',
144
+ 'cwd',
145
+ '-p',
146
+ `${pid}`
147
+ ], {
148
+ timeout
149
+ });
150
+ const processCWD = (_stdout_split_find = stdout.split('\n').find((output)=>output.startsWith('n'))) == null ? void 0 : _stdout_split_find.slice(1);
151
+ return processCWD && _path().isAbsolute(processCWD) ? _path().normalize(processCWD) : null;
152
+ } catch {
153
+ return null;
154
+ }
119
155
  }
120
- function getRunningProcess(port) {
121
- // 63828
122
- const pid = getPID(port);
123
- if (!pid) {
156
+ async function getRunningProcess(port) {
157
+ // Don't even try on Windows, since `lsof` and `ps` are not available there
158
+ if (process.platform === 'win32') {
124
159
  return null;
125
160
  }
126
- try {
127
- // /Users/evanbacon/Documents/GitHub/lab/myapp
128
- const directory = getDirectoryOfProcessById(pid);
129
- // /Users/evanbacon/Documents/GitHub/lab/myapp/package.json
130
- const command = getProcessCommand(pid, directory);
131
- // TODO: Have a better message for reusing another process.
132
- return {
133
- pid,
134
- directory,
135
- command
136
- };
137
- } catch {
161
+ const pid = await getPID(port);
162
+ if (!pid) {
138
163
  return null;
139
164
  }
165
+ try {
166
+ const directory = await getDirectoryOfProcessById(pid);
167
+ if (directory) {
168
+ const command = await getProcessCommand(pid, directory);
169
+ if (command) {
170
+ return {
171
+ pid,
172
+ directory,
173
+ command
174
+ };
175
+ }
176
+ }
177
+ } catch {}
178
+ return null;
140
179
  }
141
180
 
142
181
  //# sourceMappingURL=getRunningProcess.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/getRunningProcess.ts"],"sourcesContent":["import { execFileSync, execSync, ExecSyncOptionsWithStringEncoding } from 'child_process';\nimport * as path from 'path';\n\nconst debug = require('debug')('expo:utils:getRunningProcess') as typeof console.log;\n\nconst defaultOptions: ExecSyncOptionsWithStringEncoding = {\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'ignore'],\n};\n\n/** Returns a pid value for a running port like `63828` or null if nothing is running on the given port. */\nexport function getPID(port: number): number | null {\n try {\n const results = execFileSync('lsof', [`-i:${port}`, '-P', '-t', '-sTCP:LISTEN'], defaultOptions)\n .split('\\n')[0]\n .trim();\n const pid = Number(results);\n debug(`pid: ${pid} for port: ${port}`);\n return pid;\n } catch (error: any) {\n debug(`No pid found for port: ${port}. Error: ${error}`);\n return null;\n }\n}\n\n/** Get `package.json` `name` field for a given directory. Returns `null` if none exist. */\nfunction getPackageName(packageRoot: string): string | null {\n const packageJson = path.join(packageRoot, 'package.json');\n try {\n return require(packageJson).name || null;\n } catch {\n return null;\n }\n}\n\n/** Returns a command like `node /Users/evanbacon/.../bin/expo start` or the package.json name. */\nfunction getProcessCommand(pid: number, procDirectory: string): string {\n const name = getPackageName(procDirectory);\n\n if (name) {\n return name;\n }\n return execSync(`ps -o command -p ${pid} | sed -n 2p`, defaultOptions).replace(/\\n$/, '').trim();\n}\n\n/** Get directory for a given process ID. */\nexport function getDirectoryOfProcessById(processId: number): string {\n return execSync(\n `lsof -p ${processId} | awk '$4==\"cwd\" {for (i=9; i<=NF; i++) printf \"%s \", $i}'`,\n defaultOptions\n ).trim();\n}\n\n/** Get information about a running process given a port. Returns null if no process is running on the given port. */\nexport function getRunningProcess(port: number): {\n /** The PID value for the port. */\n pid: number;\n /** Get the directory for the running process. */\n directory: string;\n /** The command running the process like `node /Users/evanbacon/.../bin/expo start` or the `package.json` name like `my-app`. */\n command: string;\n} | null {\n // 63828\n const pid = getPID(port);\n if (!pid) {\n return null;\n }\n\n try {\n // /Users/evanbacon/Documents/GitHub/lab/myapp\n const directory = getDirectoryOfProcessById(pid);\n // /Users/evanbacon/Documents/GitHub/lab/myapp/package.json\n const command = getProcessCommand(pid, directory);\n // TODO: Have a better message for reusing another process.\n return { pid, directory, command };\n } catch {\n return null;\n }\n}\n"],"names":["getDirectoryOfProcessById","getPID","getRunningProcess","debug","require","defaultOptions","encoding","stdio","port","results","execFileSync","split","trim","pid","Number","error","getPackageName","packageRoot","packageJson","path","join","name","getProcessCommand","procDirectory","execSync","replace","processId","directory","command"],"mappings":";;;;;;;;;;;IA8CgBA,yBAAyB;eAAzBA;;IAnCAC,MAAM;eAANA;;IA2CAC,iBAAiB;eAAjBA;;;;yBAtD0D;;;;;;;iEACpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEtB,MAAMC,QAAQC,QAAQ,SAAS;AAE/B,MAAMC,iBAAoD;IACxDC,UAAU;IACVC,OAAO;QAAC;QAAQ;QAAQ;KAAS;AACnC;AAGO,SAASN,OAAOO,IAAY;IACjC,IAAI;QACF,MAAMC,UAAUC,IAAAA,6BAAY,EAAC,QAAQ;YAAC,CAAC,GAAG,EAAEF,MAAM;YAAE;YAAM;YAAM;SAAe,EAAEH,gBAC9EM,KAAK,CAAC,KAAK,CAAC,EAAE,CACdC,IAAI;QACP,MAAMC,MAAMC,OAAOL;QACnBN,MAAM,CAAC,KAAK,EAAEU,IAAI,WAAW,EAAEL,MAAM;QACrC,OAAOK;IACT,EAAE,OAAOE,OAAY;QACnBZ,MAAM,CAAC,uBAAuB,EAAEK,KAAK,SAAS,EAAEO,OAAO;QACvD,OAAO;IACT;AACF;AAEA,yFAAyF,GACzF,SAASC,eAAeC,WAAmB;IACzC,MAAMC,cAAcC,QAAKC,IAAI,CAACH,aAAa;IAC3C,IAAI;QACF,OAAOb,QAAQc,aAAaG,IAAI,IAAI;IACtC,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,gGAAgG,GAChG,SAASC,kBAAkBT,GAAW,EAAEU,aAAqB;IAC3D,MAAMF,OAAOL,eAAeO;IAE5B,IAAIF,MAAM;QACR,OAAOA;IACT;IACA,OAAOG,IAAAA,yBAAQ,EAAC,CAAC,iBAAiB,EAAEX,IAAI,YAAY,CAAC,EAAER,gBAAgBoB,OAAO,CAAC,OAAO,IAAIb,IAAI;AAChG;AAGO,SAASZ,0BAA0B0B,SAAiB;IACzD,OAAOF,IAAAA,yBAAQ,EACb,CAAC,QAAQ,EAAEE,UAAU,2DAA2D,CAAC,EACjFrB,gBACAO,IAAI;AACR;AAGO,SAASV,kBAAkBM,IAAY;IAQ5C,QAAQ;IACR,MAAMK,MAAMZ,OAAOO;IACnB,IAAI,CAACK,KAAK;QACR,OAAO;IACT;IAEA,IAAI;QACF,8CAA8C;QAC9C,MAAMc,YAAY3B,0BAA0Ba;QAC5C,2DAA2D;QAC3D,MAAMe,UAAUN,kBAAkBT,KAAKc;QACvC,2DAA2D;QAC3D,OAAO;YAAEd;YAAKc;YAAWC;QAAQ;IACnC,EAAE,OAAM;QACN,OAAO;IACT;AACF"}
1
+ {"version":3,"sources":["../../../src/utils/getRunningProcess.ts"],"sourcesContent":["import spawnAsync from '@expo/spawn-async';\nimport * as path from 'path';\n\nconst debug = require('debug')('expo:utils:getRunningProcess') as typeof console.log;\n\n/** Timeout applied to shell commands */\nconst timeout = 350;\n\n/** Returns a pid value for a running port like `63828` or null if nothing is running on the given port. */\nexport async function getPID(port: number): Promise<number | null> {\n try {\n const { stdout } = await spawnAsync('lsof', [`-i:${port}`, '-P', '-t', '-sTCP:LISTEN'], {\n timeout,\n });\n const pid = Number(stdout.split('\\n', 1)[0].trim());\n debug(`pid: ${pid} for port: ${port}`);\n return Number.isSafeInteger(pid) ? pid : null;\n } catch (error: any) {\n debug(`No pid found for port: ${port}. Error: ${error}`);\n return null;\n }\n}\n\n/** Get `package.json` `name` field for a given directory. Returns `null` if none exist. */\nfunction getPackageName(packageRoot: string): string | null {\n try {\n const packageJson = path.resolve(packageRoot, 'package.json');\n return require(packageJson).name || null;\n } catch (error) {\n return null;\n }\n}\n\n/** Returns a command like `node /Users/evanbacon/.../bin/expo start` or the package.json name. */\nexport async function getProcessCommand(\n pid: number,\n procDirectory: string\n): Promise<string | null> {\n let name = getPackageName(procDirectory);\n if (!name) {\n // ps\n // -o args=: Output argv without header\n // -p [pid]: For process of PID\n const { stdout } = await spawnAsync('ps', ['-o', 'args=', '-p', `${pid}`], {\n timeout,\n });\n name = stdout.trim();\n }\n return name || null;\n}\n\n/** Get directory for a given process ID. */\nexport async function getDirectoryOfProcessById(pid: number): Promise<string | null> {\n try {\n // lsof\n // -F n: ask for machine readable output\n // -a: apply conditions as logical AND\n // -d cwd: Filter by cwd fd\n // -p [pid]: Filter by input process id\n const { stdout } = await spawnAsync('lsof', ['-F', 'n', '-a', '-d', 'cwd', '-p', `${pid}`], {\n timeout,\n });\n const processCWD = stdout\n .split('\\n')\n .find((output) => output.startsWith('n'))\n ?.slice(1);\n return processCWD && path.isAbsolute(processCWD) ? path.normalize(processCWD) : null;\n } catch {\n return null;\n }\n}\n\ninterface RunningProcess {\n /** The PID value for the port. */\n pid: number;\n /** Get the directory for the running process. */\n directory: string;\n /** The command running the process like `node /Users/evanbacon/.../bin/expo start` or the `package.json` name like `my-app`. */\n command: string;\n}\n\n/** Get information about a running process given a port. Returns null if no process is running on the given port. */\nexport async function getRunningProcess(port: number): Promise<RunningProcess | null> {\n // Don't even try on Windows, since `lsof` and `ps` are not available there\n if (process.platform === 'win32') {\n return null;\n }\n\n const pid = await getPID(port);\n if (!pid) {\n return null;\n }\n try {\n const directory = await getDirectoryOfProcessById(pid);\n if (directory) {\n const command = await getProcessCommand(pid, directory);\n if (command) {\n return { pid, directory, command };\n }\n }\n } catch {}\n return null;\n}\n"],"names":["getDirectoryOfProcessById","getPID","getProcessCommand","getRunningProcess","debug","require","timeout","port","stdout","spawnAsync","pid","Number","split","trim","isSafeInteger","error","getPackageName","packageRoot","packageJson","path","resolve","name","procDirectory","processCWD","find","output","startsWith","slice","isAbsolute","normalize","process","platform","directory","command"],"mappings":";;;;;;;;;;;IAoDsBA,yBAAyB;eAAzBA;;IA3CAC,MAAM;eAANA;;IAyBAC,iBAAiB;eAAjBA;;IAgDAC,iBAAiB;eAAjBA;;;;gEAlFC;;;;;;;iEACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEtB,MAAMC,QAAQC,QAAQ,SAAS;AAE/B,sCAAsC,GACtC,MAAMC,UAAU;AAGT,eAAeL,OAAOM,IAAY;IACvC,IAAI;QACF,MAAM,EAAEC,MAAM,EAAE,GAAG,MAAMC,IAAAA,qBAAU,EAAC,QAAQ;YAAC,CAAC,GAAG,EAAEF,MAAM;YAAE;YAAM;YAAM;SAAe,EAAE;YACtFD;QACF;QACA,MAAMI,MAAMC,OAAOH,OAAOI,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,CAACC,IAAI;QAChDT,MAAM,CAAC,KAAK,EAAEM,IAAI,WAAW,EAAEH,MAAM;QACrC,OAAOI,OAAOG,aAAa,CAACJ,OAAOA,MAAM;IAC3C,EAAE,OAAOK,OAAY;QACnBX,MAAM,CAAC,uBAAuB,EAAEG,KAAK,SAAS,EAAEQ,OAAO;QACvD,OAAO;IACT;AACF;AAEA,yFAAyF,GACzF,SAASC,eAAeC,WAAmB;IACzC,IAAI;QACF,MAAMC,cAAcC,QAAKC,OAAO,CAACH,aAAa;QAC9C,OAAOZ,QAAQa,aAAaG,IAAI,IAAI;IACtC,EAAE,OAAON,OAAO;QACd,OAAO;IACT;AACF;AAGO,eAAeb,kBACpBQ,GAAW,EACXY,aAAqB;IAErB,IAAID,OAAOL,eAAeM;IAC1B,IAAI,CAACD,MAAM;QACT,KAAK;QACL,uCAAuC;QACvC,+BAA+B;QAC/B,MAAM,EAAEb,MAAM,EAAE,GAAG,MAAMC,IAAAA,qBAAU,EAAC,MAAM;YAAC;YAAM;YAAS;YAAM,GAAGC,KAAK;SAAC,EAAE;YACzEJ;QACF;QACAe,OAAOb,OAAOK,IAAI;IACpB;IACA,OAAOQ,QAAQ;AACjB;AAGO,eAAerB,0BAA0BU,GAAW;IACzD,IAAI;YASiBF;QARnB,OAAO;QACP,wCAAwC;QACxC,sCAAsC;QACtC,2BAA2B;QAC3B,uCAAuC;QACvC,MAAM,EAAEA,MAAM,EAAE,GAAG,MAAMC,IAAAA,qBAAU,EAAC,QAAQ;YAAC;YAAM;YAAK;YAAM;YAAM;YAAO;YAAM,GAAGC,KAAK;SAAC,EAAE;YAC1FJ;QACF;QACA,MAAMiB,cAAaf,qBAAAA,OAChBI,KAAK,CAAC,MACNY,IAAI,CAAC,CAACC,SAAWA,OAAOC,UAAU,CAAC,0BAFnBlB,mBAGfmB,KAAK,CAAC;QACV,OAAOJ,cAAcJ,QAAKS,UAAU,CAACL,cAAcJ,QAAKU,SAAS,CAACN,cAAc;IAClF,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAYO,eAAepB,kBAAkBI,IAAY;IAClD,2EAA2E;IAC3E,IAAIuB,QAAQC,QAAQ,KAAK,SAAS;QAChC,OAAO;IACT;IAEA,MAAMrB,MAAM,MAAMT,OAAOM;IACzB,IAAI,CAACG,KAAK;QACR,OAAO;IACT;IACA,IAAI;QACF,MAAMsB,YAAY,MAAMhC,0BAA0BU;QAClD,IAAIsB,WAAW;YACb,MAAMC,UAAU,MAAM/B,kBAAkBQ,KAAKsB;YAC7C,IAAIC,SAAS;gBACX,OAAO;oBAAEvB;oBAAKsB;oBAAWC;gBAAQ;YACnC;QACF;IACF,EAAE,OAAM,CAAC;IACT,OAAO;AACT"}
@@ -2,10 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "getIpAddress", {
6
- enumerable: true,
7
- get: function() {
8
- return getIpAddress;
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ getGateway: function() {
13
+ return getGateway;
14
+ },
15
+ getGatewayAsync: function() {
16
+ return getGatewayAsync;
17
+ },
18
+ getIpAddressAsync: function() {
19
+ return getIpAddressAsync;
9
20
  }
10
21
  });
11
22
  function _lannetwork() {
@@ -15,13 +26,38 @@ function _lannetwork() {
15
26
  };
16
27
  return data;
17
28
  }
18
- function getIpAddress() {
29
+ const _env = require("./env");
30
+ // NOTE(@kitten): In headless mode, there's no point in trying to run DHCP, since
31
+ // we assume we're online and probing is going to be enough
32
+ const options = {
33
+ noDhcp: (0, _env.envIsHeadless)()
34
+ };
35
+ function getGateway() {
36
+ try {
37
+ return (0, _lannetwork().lanNetworkSync)(options);
38
+ } catch {
39
+ return {
40
+ iname: null,
41
+ address: '127.0.0.1',
42
+ gateway: null,
43
+ internal: true
44
+ };
45
+ }
46
+ }
47
+ async function getGatewayAsync() {
19
48
  try {
20
- const lan = (0, _lannetwork().lanNetworkSync)();
21
- return lan.address;
49
+ return await (0, _lannetwork().lanNetwork)(options);
22
50
  } catch {
23
- return '127.0.0.1';
51
+ return {
52
+ iname: null,
53
+ address: '127.0.0.1',
54
+ gateway: null,
55
+ internal: true
56
+ };
24
57
  }
25
58
  }
59
+ async function getIpAddressAsync() {
60
+ return (await getGatewayAsync()).address;
61
+ }
26
62
 
27
63
  //# sourceMappingURL=ip.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/ip.ts"],"sourcesContent":["import { lanNetworkSync } from 'lan-network';\n\nexport function getIpAddress(): string {\n try {\n const lan = lanNetworkSync();\n return lan.address;\n } catch {\n return '127.0.0.1';\n }\n}\n"],"names":["getIpAddress","lan","lanNetworkSync","address"],"mappings":";;;;+BAEgBA;;;eAAAA;;;;yBAFe;;;;;;AAExB,SAASA;IACd,IAAI;QACF,MAAMC,MAAMC,IAAAA,4BAAc;QAC1B,OAAOD,IAAIE,OAAO;IACpB,EAAE,OAAM;QACN,OAAO;IACT;AACF"}
1
+ {"version":3,"sources":["../../../src/utils/ip.ts"],"sourcesContent":["import { lanNetworkSync, lanNetwork } from 'lan-network';\n\nimport { envIsHeadless } from './env';\n\n// NOTE(@kitten): In headless mode, there's no point in trying to run DHCP, since\n// we assume we're online and probing is going to be enough\nconst options = {\n noDhcp: envIsHeadless(),\n};\n\nexport interface GatewayInfo {\n iname: string | null;\n address: string;\n gateway: string | null;\n internal: boolean;\n}\n\nexport function getGateway(): GatewayInfo {\n try {\n return lanNetworkSync(options);\n } catch {\n return {\n iname: null,\n address: '127.0.0.1',\n gateway: null,\n internal: true,\n };\n }\n}\n\nexport async function getGatewayAsync(): Promise<GatewayInfo> {\n try {\n return await lanNetwork(options);\n } catch {\n return {\n iname: null,\n address: '127.0.0.1',\n gateway: null,\n internal: true,\n };\n }\n}\n\nexport async function getIpAddressAsync(): Promise<string> {\n return (await getGatewayAsync()).address;\n}\n"],"names":["getGateway","getGatewayAsync","getIpAddressAsync","options","noDhcp","envIsHeadless","lanNetworkSync","iname","address","gateway","internal","lanNetwork"],"mappings":";;;;;;;;;;;IAiBgBA,UAAU;eAAVA;;IAaMC,eAAe;eAAfA;;IAaAC,iBAAiB;eAAjBA;;;;yBA3CqB;;;;;;qBAEb;AAE9B,iFAAiF;AACjF,2DAA2D;AAC3D,MAAMC,UAAU;IACdC,QAAQC,IAAAA,kBAAa;AACvB;AASO,SAASL;IACd,IAAI;QACF,OAAOM,IAAAA,4BAAc,EAACH;IACxB,EAAE,OAAM;QACN,OAAO;YACLI,OAAO;YACPC,SAAS;YACTC,SAAS;YACTC,UAAU;QACZ;IACF;AACF;AAEO,eAAeT;IACpB,IAAI;QACF,OAAO,MAAMU,IAAAA,wBAAU,EAACR;IAC1B,EAAE,OAAM;QACN,OAAO;YACLI,OAAO;YACPC,SAAS;YACTC,SAAS;YACTC,UAAU;QACZ;IACF;AACF;AAEO,eAAeR;IACpB,OAAO,AAAC,CAAA,MAAMD,iBAAgB,EAAGO,OAAO;AAC1C"}
@@ -9,9 +9,15 @@ function _export(target, all) {
9
9
  });
10
10
  }
11
11
  _export(exports, {
12
+ getEnvFiles: function() {
13
+ return getEnvFiles;
14
+ },
12
15
  loadEnvFiles: function() {
13
16
  return loadEnvFiles;
14
17
  },
18
+ reloadEnvFiles: function() {
19
+ return reloadEnvFiles;
20
+ },
15
21
  setNodeEnv: function() {
16
22
  return setNodeEnv;
17
23
  }
@@ -23,6 +29,18 @@ function _env() {
23
29
  };
24
30
  return data;
25
31
  }
32
+ function _nodepath() {
33
+ const data = /*#__PURE__*/ _interop_require_default(require("node:path"));
34
+ _nodepath = function() {
35
+ return data;
36
+ };
37
+ return data;
38
+ }
39
+ function _interop_require_default(obj) {
40
+ return obj && obj.__esModule ? obj : {
41
+ default: obj
42
+ };
43
+ }
26
44
  function _getRequireWildcardCache(nodeInterop) {
27
45
  if (typeof WeakMap !== "function") return null;
28
46
  var cacheBabelInterop = new WeakMap();
@@ -69,8 +87,55 @@ function setNodeEnv(mode) {
69
87
  process.env.BABEL_ENV = process.env.BABEL_ENV || process.env.NODE_ENV;
70
88
  globalThis.__DEV__ = process.env.NODE_ENV !== 'production';
71
89
  }
90
+ let prevEnvKeys;
72
91
  function loadEnvFiles(projectRoot, options) {
73
- return _env().load(projectRoot, options);
92
+ const params = {
93
+ ...options,
94
+ force: !!(options == null ? void 0 : options.force),
95
+ silent: !!(options == null ? void 0 : options.silent),
96
+ mode: process.env.NODE_ENV,
97
+ systemEnv: process.env
98
+ };
99
+ const envInfo = _env().loadProjectEnv(projectRoot, params);
100
+ const envOutput = {};
101
+ if (envInfo.result === 'loaded') {
102
+ prevEnvKeys = new Set();
103
+ for (const key of envInfo.loaded){
104
+ envOutput[key] = envInfo.env[key] ?? undefined;
105
+ prevEnvKeys.add(key);
106
+ }
107
+ }
108
+ _env().logLoadedEnv(envInfo, params);
109
+ return process.env;
110
+ }
111
+ function getEnvFiles(projectRoot) {
112
+ return _env().getEnvFiles({
113
+ mode: process.env.NODE_ENV
114
+ }).map((fileName)=>_nodepath().default.join(projectRoot, fileName));
115
+ }
116
+ function reloadEnvFiles(projectRoot) {
117
+ const isEnabled = _env().isEnabled();
118
+ if (isEnabled) {
119
+ const params = {
120
+ force: true,
121
+ silent: true,
122
+ mode: process.env.NODE_ENV,
123
+ systemEnv: process.env
124
+ };
125
+ // We use a global tracker to allow overwrites of env vars we set ourselves
126
+ const envInfo = _env().parseProjectEnv(projectRoot, params);
127
+ const envOutput = {};
128
+ for(const key in envInfo.env){
129
+ const value = envInfo.env[key];
130
+ if (process.env[key] !== value) {
131
+ if (typeof process.env[key] === 'undefined' || (!prevEnvKeys || prevEnvKeys.has(key)) && process.env[key] !== value) {
132
+ (prevEnvKeys ||= new Set()).add(key);
133
+ process.env[key] = envInfo.env[key];
134
+ envOutput[key] = value ?? undefined;
135
+ }
136
+ }
137
+ }
138
+ }
74
139
  }
75
140
 
76
141
  //# sourceMappingURL=nodeEnv.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/nodeEnv.ts"],"sourcesContent":["import * as env from '@expo/env';\n\n// TODO(@kitten): We assign this here to run server-side code bundled by metro\n// It's not isolated into a worker thread yet\ndeclare namespace globalThis {\n let __DEV__: boolean | undefined;\n}\n\n/**\n * Set the environment to production or development\n * lots of tools use this to determine if they should run in a dev mode.\n */\nexport function setNodeEnv(mode: 'development' | 'production') {\n process.env.NODE_ENV = process.env.NODE_ENV || mode;\n process.env.BABEL_ENV = process.env.BABEL_ENV || process.env.NODE_ENV;\n globalThis.__DEV__ = process.env.NODE_ENV !== 'production';\n}\n\n/**\n * Load the dotenv files into the current `process.env` scope.\n * Note, this requires `NODE_ENV` being set through `setNodeEnv`.\n */\nexport function loadEnvFiles(projectRoot: string, options?: Parameters<typeof env.load>[1]) {\n return env.load(projectRoot, options);\n}\n"],"names":["loadEnvFiles","setNodeEnv","mode","process","env","NODE_ENV","BABEL_ENV","globalThis","__DEV__","projectRoot","options","load"],"mappings":";;;;;;;;;;;IAsBgBA,YAAY;eAAZA;;IAVAC,UAAU;eAAVA;;;;iEAZK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYd,SAASA,WAAWC,IAAkC;IAC3DC,QAAQC,GAAG,CAACC,QAAQ,GAAGF,QAAQC,GAAG,CAACC,QAAQ,IAAIH;IAC/CC,QAAQC,GAAG,CAACE,SAAS,GAAGH,QAAQC,GAAG,CAACE,SAAS,IAAIH,QAAQC,GAAG,CAACC,QAAQ;IACrEE,WAAWC,OAAO,GAAGL,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAChD;AAMO,SAASL,aAAaS,WAAmB,EAAEC,OAAwC;IACxF,OAAON,OAAIO,IAAI,CAACF,aAAaC;AAC/B"}
1
+ {"version":3,"sources":["../../../src/utils/nodeEnv.ts"],"sourcesContent":["import * as env from '@expo/env';\nimport path from 'node:path';\n\ntype EnvOutput = Record<string, string | undefined>;\n\n// TODO(@kitten): We assign this here to run server-side code bundled by metro\n// It's not isolated into a worker thread yet\ndeclare namespace globalThis {\n let __DEV__: boolean | undefined;\n}\n\n/**\n * Set the environment to production or development\n * lots of tools use this to determine if they should run in a dev mode.\n */\nexport function setNodeEnv(mode: 'development' | 'production') {\n process.env.NODE_ENV = process.env.NODE_ENV || mode;\n process.env.BABEL_ENV = process.env.BABEL_ENV || process.env.NODE_ENV;\n globalThis.__DEV__ = process.env.NODE_ENV !== 'production';\n}\n\ninterface LoadEnvFilesOptions {\n force?: boolean;\n silent?: boolean;\n mode?: string;\n}\n\nlet prevEnvKeys: Set<string> | undefined;\n\n/**\n * Load the dotenv files into the current `process.env` scope.\n * Note, this requires `NODE_ENV` being set through `setNodeEnv`.\n */\nexport function loadEnvFiles(projectRoot: string, options?: LoadEnvFilesOptions) {\n const params = {\n ...options,\n force: !!options?.force,\n silent: !!options?.silent,\n mode: process.env.NODE_ENV,\n systemEnv: process.env,\n };\n\n const envInfo = env.loadProjectEnv(projectRoot, params);\n const envOutput: EnvOutput = {};\n if (envInfo.result === 'loaded') {\n prevEnvKeys = new Set();\n for (const key of envInfo.loaded) {\n envOutput[key] = envInfo.env[key] ?? undefined;\n prevEnvKeys.add(key);\n }\n }\n\n env.logLoadedEnv(envInfo, params);\n return process.env;\n}\n\nexport function getEnvFiles(projectRoot: string) {\n return env\n .getEnvFiles({ mode: process.env.NODE_ENV })\n .map((fileName) => path.join(projectRoot, fileName));\n}\n\nexport function reloadEnvFiles(projectRoot: string) {\n const isEnabled = env.isEnabled();\n if (isEnabled) {\n const params = {\n force: true,\n silent: true,\n mode: process.env.NODE_ENV,\n systemEnv: process.env,\n };\n\n // We use a global tracker to allow overwrites of env vars we set ourselves\n const envInfo = env.parseProjectEnv(projectRoot, params);\n const envOutput: EnvOutput = {};\n for (const key in envInfo.env) {\n const value = envInfo.env[key];\n if (process.env[key] !== value) {\n if (\n typeof process.env[key] === 'undefined' ||\n ((!prevEnvKeys || prevEnvKeys.has(key)) && process.env[key] !== value)\n ) {\n (prevEnvKeys ||= new Set()).add(key);\n process.env[key] = envInfo.env[key];\n envOutput[key] = value ?? undefined;\n }\n }\n }\n }\n}\n"],"names":["getEnvFiles","loadEnvFiles","reloadEnvFiles","setNodeEnv","mode","process","env","NODE_ENV","BABEL_ENV","globalThis","__DEV__","prevEnvKeys","projectRoot","options","params","force","silent","systemEnv","envInfo","loadProjectEnv","envOutput","result","Set","key","loaded","undefined","add","logLoadedEnv","map","fileName","path","join","isEnabled","parseProjectEnv","value","has"],"mappings":";;;;;;;;;;;IAwDgBA,WAAW;eAAXA;;IAvBAC,YAAY;eAAZA;;IA6BAC,cAAc;eAAdA;;IA/CAC,UAAU;eAAVA;;;;iEAfK;;;;;;;gEACJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcV,SAASA,WAAWC,IAAkC;IAC3DC,QAAQC,GAAG,CAACC,QAAQ,GAAGF,QAAQC,GAAG,CAACC,QAAQ,IAAIH;IAC/CC,QAAQC,GAAG,CAACE,SAAS,GAAGH,QAAQC,GAAG,CAACE,SAAS,IAAIH,QAAQC,GAAG,CAACC,QAAQ;IACrEE,WAAWC,OAAO,GAAGL,QAAQC,GAAG,CAACC,QAAQ,KAAK;AAChD;AAQA,IAAII;AAMG,SAASV,aAAaW,WAAmB,EAAEC,OAA6B;IAC7E,MAAMC,SAAS;QACb,GAAGD,OAAO;QACVE,OAAO,CAAC,EAACF,2BAAAA,QAASE,KAAK;QACvBC,QAAQ,CAAC,EAACH,2BAAAA,QAASG,MAAM;QACzBZ,MAAMC,QAAQC,GAAG,CAACC,QAAQ;QAC1BU,WAAWZ,QAAQC,GAAG;IACxB;IAEA,MAAMY,UAAUZ,OAAIa,cAAc,CAACP,aAAaE;IAChD,MAAMM,YAAuB,CAAC;IAC9B,IAAIF,QAAQG,MAAM,KAAK,UAAU;QAC/BV,cAAc,IAAIW;QAClB,KAAK,MAAMC,OAAOL,QAAQM,MAAM,CAAE;YAChCJ,SAAS,CAACG,IAAI,GAAGL,QAAQZ,GAAG,CAACiB,IAAI,IAAIE;YACrCd,YAAYe,GAAG,CAACH;QAClB;IACF;IAEAjB,OAAIqB,YAAY,CAACT,SAASJ;IAC1B,OAAOT,QAAQC,GAAG;AACpB;AAEO,SAASN,YAAYY,WAAmB;IAC7C,OAAON,OACJN,WAAW,CAAC;QAAEI,MAAMC,QAAQC,GAAG,CAACC,QAAQ;IAAC,GACzCqB,GAAG,CAAC,CAACC,WAAaC,mBAAI,CAACC,IAAI,CAACnB,aAAaiB;AAC9C;AAEO,SAAS3B,eAAeU,WAAmB;IAChD,MAAMoB,YAAY1B,OAAI0B,SAAS;IAC/B,IAAIA,WAAW;QACb,MAAMlB,SAAS;YACbC,OAAO;YACPC,QAAQ;YACRZ,MAAMC,QAAQC,GAAG,CAACC,QAAQ;YAC1BU,WAAWZ,QAAQC,GAAG;QACxB;QAEA,2EAA2E;QAC3E,MAAMY,UAAUZ,OAAI2B,eAAe,CAACrB,aAAaE;QACjD,MAAMM,YAAuB,CAAC;QAC9B,IAAK,MAAMG,OAAOL,QAAQZ,GAAG,CAAE;YAC7B,MAAM4B,QAAQhB,QAAQZ,GAAG,CAACiB,IAAI;YAC9B,IAAIlB,QAAQC,GAAG,CAACiB,IAAI,KAAKW,OAAO;gBAC9B,IACE,OAAO7B,QAAQC,GAAG,CAACiB,IAAI,KAAK,eAC3B,AAAC,CAAA,CAACZ,eAAeA,YAAYwB,GAAG,CAACZ,IAAG,KAAMlB,QAAQC,GAAG,CAACiB,IAAI,KAAKW,OAChE;oBACCvB,CAAAA,gBAAgB,IAAIW,KAAI,EAAGI,GAAG,CAACH;oBAChClB,QAAQC,GAAG,CAACiB,IAAI,GAAGL,QAAQZ,GAAG,CAACiB,IAAI;oBACnCH,SAAS,CAACG,IAAI,GAAGW,SAAST;gBAC5B;YACF;QACF;IACF;AACF"}
@@ -116,7 +116,7 @@ function isRestrictedPort(port) {
116
116
  }
117
117
  async function isBusyPortRunningSameProcessAsync(projectRoot, { port }) {
118
118
  const { getRunningProcess } = require('./getRunningProcess');
119
- const runningProcess = isRestrictedPort(port) ? null : getRunningProcess(port);
119
+ const runningProcess = isRestrictedPort(port) ? null : await getRunningProcess(port);
120
120
  if (runningProcess) {
121
121
  if (runningProcess.directory === projectRoot) {
122
122
  return true;
@@ -137,7 +137,7 @@ async function choosePortAsync(projectRoot, { defaultPort, host, reuseExistingPo
137
137
  const isRestricted = port && isRestrictedPort(port);
138
138
  let message = isRestricted ? `Admin permissions are required to run a server on a port below 1024` : `Port ${_chalk().default.bold(defaultPort)} is`;
139
139
  const { getRunningProcess } = require('./getRunningProcess');
140
- const runningProcess = isRestricted ? null : getRunningProcess(defaultPort);
140
+ const runningProcess = isRestricted ? null : await getRunningProcess(defaultPort);
141
141
  if (runningProcess) {
142
142
  const pidTag = _chalk().default.gray(`(pid ${runningProcess.pid})`);
143
143
  if (runningProcess.directory === projectRoot) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/port.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { env } from './env';\nimport { CommandError } from './errors';\nimport { testPortAsync, freePortAsync } from './freeport';\nimport * as Log from '../log';\n\n/** Get a free port or assert a CLI command error. */\nexport async function getFreePortAsync(rangeStart: number): Promise<number> {\n const port = await freePortAsync(rangeStart, [null, 'localhost']);\n if (!port) {\n throw new CommandError('NO_PORT_FOUND', 'No available port found');\n }\n\n return port;\n}\n\n/** @return `true` if the port can still be used to start the dev server, `false` if the dev server should be skipped, and asserts if the port is now taken. */\nexport async function ensurePortAvailabilityAsync(\n projectRoot: string,\n { port }: { port: number }\n): Promise<boolean> {\n const isFreePort = await testPortAsync(port, [null]);\n // Check if port has become busy during the build.\n if (isFreePort) {\n return true;\n }\n\n const isBusy = await isBusyPortRunningSameProcessAsync(projectRoot, { port });\n if (!isBusy) {\n throw new CommandError(\n `Port \"${port}\" became busy running another process while the app was compiling. Re-run command to use a new port.`\n );\n }\n\n // Log that the dev server will not be started and that the logs will appear in another window.\n Log.log(\n '› The dev server for this app is already running in another window. Logs will appear there.'\n );\n return false;\n}\n\nfunction isRestrictedPort(port: number) {\n if (process.platform !== 'win32' && port < 1024) {\n const isRoot = process.getuid && process.getuid() === 0;\n return !isRoot;\n }\n return false;\n}\n\nasync function isBusyPortRunningSameProcessAsync(projectRoot: string, { port }: { port: number }) {\n const { getRunningProcess } =\n require('./getRunningProcess') as typeof import('./getRunningProcess');\n\n const runningProcess = isRestrictedPort(port) ? null : getRunningProcess(port);\n if (runningProcess) {\n if (runningProcess.directory === projectRoot) {\n return true;\n } else {\n return false;\n }\n }\n\n return null;\n}\n\n// TODO(Bacon): Revisit after all start and run code is merged.\nexport async function choosePortAsync(\n projectRoot: string,\n {\n defaultPort,\n host,\n reuseExistingPort,\n }: {\n defaultPort: number;\n host?: string;\n reuseExistingPort?: boolean;\n }\n): Promise<number | null> {\n try {\n const port = await freePortAsync(defaultPort, [host ?? null]);\n if (port === defaultPort || defaultPort === 0) {\n return port;\n }\n\n const isRestricted = port && isRestrictedPort(port);\n\n let message = isRestricted\n ? `Admin permissions are required to run a server on a port below 1024`\n : `Port ${chalk.bold(defaultPort)} is`;\n\n const { getRunningProcess } =\n require('./getRunningProcess') as typeof import('./getRunningProcess');\n const runningProcess = isRestricted ? null : getRunningProcess(defaultPort);\n\n if (runningProcess) {\n const pidTag = chalk.gray(`(pid ${runningProcess.pid})`);\n if (runningProcess.directory === projectRoot) {\n message += ` running this app in another window`;\n if (reuseExistingPort) {\n return null;\n }\n } else {\n message += ` running ${chalk.cyan(runningProcess.command)} in another window`;\n }\n message += '\\n' + chalk.gray(` ${runningProcess.directory} ${pidTag}`);\n } else {\n message += ' being used by another process';\n }\n\n Log.log(`\\u203A ${message}`);\n const { confirmAsync } = require('./prompts') as typeof import('./prompts');\n const change = await confirmAsync({\n message: `Use port ${port} instead?`,\n initial: true,\n });\n return change ? port : null;\n } catch (error: any) {\n if (error.code === 'ABORTED') {\n throw error;\n } else if (error.code === 'NON_INTERACTIVE') {\n Log.warn(chalk.yellow(error.message));\n return null;\n }\n throw error;\n }\n}\n\n// TODO(Bacon): Revisit after all start and run code is merged.\nexport async function resolvePortAsync(\n projectRoot: string,\n {\n /** Should opt to reuse a port that is running the same project in another window. */\n reuseExistingPort,\n /** Preferred port. */\n defaultPort,\n /** Backup port for when the default isn't available. */\n fallbackPort,\n }: {\n reuseExistingPort?: boolean;\n defaultPort?: string | number;\n fallbackPort?: number;\n } = {}\n): Promise<number | null> {\n let port: number;\n if (typeof defaultPort === 'string') {\n port = parseInt(defaultPort, 10);\n } else if (typeof defaultPort === 'number') {\n port = defaultPort;\n } else {\n port = env.RCT_METRO_PORT || fallbackPort || 8081;\n }\n\n // Only check the port when the bundler is running.\n const resolvedPort = await choosePortAsync(projectRoot, {\n defaultPort: port,\n reuseExistingPort,\n });\n if (resolvedPort == null) {\n Log.log('\\u203A Skipping dev server');\n // Skip bundling if the port is null\n } else {\n // Use the new or resolved port\n process.env.RCT_METRO_PORT = String(resolvedPort);\n }\n\n return resolvedPort;\n}\n"],"names":["choosePortAsync","ensurePortAvailabilityAsync","getFreePortAsync","resolvePortAsync","rangeStart","port","freePortAsync","CommandError","projectRoot","isFreePort","testPortAsync","isBusy","isBusyPortRunningSameProcessAsync","Log","log","isRestrictedPort","process","platform","isRoot","getuid","getRunningProcess","require","runningProcess","directory","defaultPort","host","reuseExistingPort","isRestricted","message","chalk","bold","pidTag","gray","pid","cyan","command","confirmAsync","change","initial","error","code","warn","yellow","fallbackPort","parseInt","env","RCT_METRO_PORT","resolvedPort","String"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/utils/port.ts"],"sourcesContent":["import chalk from 'chalk';\n\nimport { env } from './env';\nimport { CommandError } from './errors';\nimport { testPortAsync, freePortAsync } from './freeport';\nimport * as Log from '../log';\n\n/** Get a free port or assert a CLI command error. */\nexport async function getFreePortAsync(rangeStart: number): Promise<number> {\n const port = await freePortAsync(rangeStart, [null, 'localhost']);\n if (!port) {\n throw new CommandError('NO_PORT_FOUND', 'No available port found');\n }\n\n return port;\n}\n\n/** @return `true` if the port can still be used to start the dev server, `false` if the dev server should be skipped, and asserts if the port is now taken. */\nexport async function ensurePortAvailabilityAsync(\n projectRoot: string,\n { port }: { port: number }\n): Promise<boolean> {\n const isFreePort = await testPortAsync(port, [null]);\n // Check if port has become busy during the build.\n if (isFreePort) {\n return true;\n }\n\n const isBusy = await isBusyPortRunningSameProcessAsync(projectRoot, { port });\n if (!isBusy) {\n throw new CommandError(\n `Port \"${port}\" became busy running another process while the app was compiling. Re-run command to use a new port.`\n );\n }\n\n // Log that the dev server will not be started and that the logs will appear in another window.\n Log.log(\n '› The dev server for this app is already running in another window. Logs will appear there.'\n );\n return false;\n}\n\nfunction isRestrictedPort(port: number) {\n if (process.platform !== 'win32' && port < 1024) {\n const isRoot = process.getuid && process.getuid() === 0;\n return !isRoot;\n }\n return false;\n}\n\nasync function isBusyPortRunningSameProcessAsync(projectRoot: string, { port }: { port: number }) {\n const { getRunningProcess } =\n require('./getRunningProcess') as typeof import('./getRunningProcess');\n const runningProcess = isRestrictedPort(port) ? null : await getRunningProcess(port);\n if (runningProcess) {\n if (runningProcess.directory === projectRoot) {\n return true;\n } else {\n return false;\n }\n }\n\n return null;\n}\n\n// TODO(Bacon): Revisit after all start and run code is merged.\nexport async function choosePortAsync(\n projectRoot: string,\n {\n defaultPort,\n host,\n reuseExistingPort,\n }: {\n defaultPort: number;\n host?: string;\n reuseExistingPort?: boolean;\n }\n): Promise<number | null> {\n try {\n const port = await freePortAsync(defaultPort, [host ?? null]);\n if (port === defaultPort || defaultPort === 0) {\n return port;\n }\n\n const isRestricted = port && isRestrictedPort(port);\n\n let message = isRestricted\n ? `Admin permissions are required to run a server on a port below 1024`\n : `Port ${chalk.bold(defaultPort)} is`;\n\n const { getRunningProcess } =\n require('./getRunningProcess') as typeof import('./getRunningProcess');\n const runningProcess = isRestricted ? null : await getRunningProcess(defaultPort);\n\n if (runningProcess) {\n const pidTag = chalk.gray(`(pid ${runningProcess.pid})`);\n if (runningProcess.directory === projectRoot) {\n message += ` running this app in another window`;\n if (reuseExistingPort) {\n return null;\n }\n } else {\n message += ` running ${chalk.cyan(runningProcess.command)} in another window`;\n }\n message += '\\n' + chalk.gray(` ${runningProcess.directory} ${pidTag}`);\n } else {\n message += ' being used by another process';\n }\n\n Log.log(`\\u203A ${message}`);\n const { confirmAsync } = require('./prompts') as typeof import('./prompts');\n const change = await confirmAsync({\n message: `Use port ${port} instead?`,\n initial: true,\n });\n return change ? port : null;\n } catch (error: any) {\n if (error.code === 'ABORTED') {\n throw error;\n } else if (error.code === 'NON_INTERACTIVE') {\n Log.warn(chalk.yellow(error.message));\n return null;\n }\n throw error;\n }\n}\n\n// TODO(Bacon): Revisit after all start and run code is merged.\nexport async function resolvePortAsync(\n projectRoot: string,\n {\n /** Should opt to reuse a port that is running the same project in another window. */\n reuseExistingPort,\n /** Preferred port. */\n defaultPort,\n /** Backup port for when the default isn't available. */\n fallbackPort,\n }: {\n reuseExistingPort?: boolean;\n defaultPort?: string | number;\n fallbackPort?: number;\n } = {}\n): Promise<number | null> {\n let port: number;\n if (typeof defaultPort === 'string') {\n port = parseInt(defaultPort, 10);\n } else if (typeof defaultPort === 'number') {\n port = defaultPort;\n } else {\n port = env.RCT_METRO_PORT || fallbackPort || 8081;\n }\n\n // Only check the port when the bundler is running.\n const resolvedPort = await choosePortAsync(projectRoot, {\n defaultPort: port,\n reuseExistingPort,\n });\n if (resolvedPort == null) {\n Log.log('\\u203A Skipping dev server');\n // Skip bundling if the port is null\n } else {\n // Use the new or resolved port\n process.env.RCT_METRO_PORT = String(resolvedPort);\n }\n\n return resolvedPort;\n}\n"],"names":["choosePortAsync","ensurePortAvailabilityAsync","getFreePortAsync","resolvePortAsync","rangeStart","port","freePortAsync","CommandError","projectRoot","isFreePort","testPortAsync","isBusy","isBusyPortRunningSameProcessAsync","Log","log","isRestrictedPort","process","platform","isRoot","getuid","getRunningProcess","require","runningProcess","directory","defaultPort","host","reuseExistingPort","isRestricted","message","chalk","bold","pidTag","gray","pid","cyan","command","confirmAsync","change","initial","error","code","warn","yellow","fallbackPort","parseInt","env","RCT_METRO_PORT","resolvedPort","String"],"mappings":"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"}
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "printQRCode", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return printQRCode;
9
+ }
10
+ });
11
+ function _nodetty() {
12
+ const data = /*#__PURE__*/ _interop_require_default(require("node:tty"));
13
+ _nodetty = function() {
14
+ return data;
15
+ };
16
+ return data;
17
+ }
18
+ function _toqr() {
19
+ const data = require("toqr");
20
+ _toqr = function() {
21
+ return data;
22
+ };
23
+ return data;
24
+ }
25
+ const _env = require("./env");
26
+ const _log = /*#__PURE__*/ _interop_require_wildcard(require("../log"));
27
+ function _interop_require_default(obj) {
28
+ return obj && obj.__esModule ? obj : {
29
+ default: obj
30
+ };
31
+ }
32
+ function _getRequireWildcardCache(nodeInterop) {
33
+ if (typeof WeakMap !== "function") return null;
34
+ var cacheBabelInterop = new WeakMap();
35
+ var cacheNodeInterop = new WeakMap();
36
+ return (_getRequireWildcardCache = function(nodeInterop) {
37
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
38
+ })(nodeInterop);
39
+ }
40
+ function _interop_require_wildcard(obj, nodeInterop) {
41
+ if (!nodeInterop && obj && obj.__esModule) {
42
+ return obj;
43
+ }
44
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
45
+ return {
46
+ default: obj
47
+ };
48
+ }
49
+ var cache = _getRequireWildcardCache(nodeInterop);
50
+ if (cache && cache.has(obj)) {
51
+ return cache.get(obj);
52
+ }
53
+ var newObj = {
54
+ __proto__: null
55
+ };
56
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
57
+ for(var key in obj){
58
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
59
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
60
+ if (desc && (desc.get || desc.set)) {
61
+ Object.defineProperty(newObj, key, desc);
62
+ } else {
63
+ newObj[key] = obj[key];
64
+ }
65
+ }
66
+ }
67
+ newObj.default = obj;
68
+ if (cache) {
69
+ cache.set(obj, newObj);
70
+ }
71
+ return newObj;
72
+ }
73
+ function printQRCode(url) {
74
+ const qr = (0, _toqr().toQR)(url);
75
+ const output = supportsSextants() ? createSextantOutput(qr) : createHalfblockOutput(qr);
76
+ return {
77
+ lines: output.split('\n').length,
78
+ print () {
79
+ _log.log(output);
80
+ }
81
+ };
82
+ }
83
+ /** On specific terminals we can print a smaller QR code */ function supportsSextants() {
84
+ var _process_env_WT_SESSION, _process_env_KITTY_WINDOW_ID, _process_env_ALACRITTY_WINDOW_ID;
85
+ if (_env.env.CI || !_nodetty().default.isatty(1) || !_nodetty().default.isatty(2)) {
86
+ return false;
87
+ } else if (process.env.COLOR === '0' || process.env.COLOR === 'false') {
88
+ return false;
89
+ }
90
+ const isWindowsTerminal = process.platform === 'win32' && !!((_process_env_WT_SESSION = process.env.WT_SESSION) == null ? void 0 : _process_env_WT_SESSION.length);
91
+ const isGhostty = process.env.TERM_PROGRAM === 'ghostty';
92
+ const isWezterm = process.env.TERM_PROGRAM === 'WezTerm';
93
+ const isKitty = !!((_process_env_KITTY_WINDOW_ID = process.env.KITTY_WINDOW_ID) == null ? void 0 : _process_env_KITTY_WINDOW_ID.length);
94
+ const isAlacritty = !!((_process_env_ALACRITTY_WINDOW_ID = process.env.ALACRITTY_WINDOW_ID) == null ? void 0 : _process_env_ALACRITTY_WINDOW_ID.length);
95
+ return isWindowsTerminal || isGhostty || isWezterm || isKitty || isAlacritty;
96
+ }
97
+ /** ANSI QR code output by using half-blocks (1x2-sized unicode blocks) */ function createHalfblockOutput(data) {
98
+ const extent = Math.sqrt(data.byteLength) | 0;
99
+ const CHAR_00 = '\u2588';
100
+ const CHAR_10 = '\u2584';
101
+ const CHAR_01 = '\u2580';
102
+ const CHAR_11 = ' ';
103
+ let output = '';
104
+ output += CHAR_10.repeat(extent + 2);
105
+ for(let row = 0; row < extent; row += 2){
106
+ output += '\n' + CHAR_00;
107
+ for(let col = 0; col < extent; col++){
108
+ const value = data[row * extent + col] << 1 | data[(row + 1) * extent + col];
109
+ switch(value){
110
+ case 0:
111
+ output += CHAR_00;
112
+ break;
113
+ case 1:
114
+ output += CHAR_01;
115
+ break;
116
+ case 2:
117
+ output += CHAR_10;
118
+ break;
119
+ case 3:
120
+ output += CHAR_11;
121
+ break;
122
+ }
123
+ }
124
+ output += CHAR_00;
125
+ }
126
+ if (extent % 2 === 0) {
127
+ output += '\n' + CHAR_01.repeat(extent + 2);
128
+ }
129
+ output += '\n';
130
+ return output;
131
+ }
132
+ /** ANSI QR code output by using sextant-blocks (2x3-sized unicode blocks) */ function createSextantOutput(data) {
133
+ const getChar = (p)=>{
134
+ // Invert then reverse
135
+ let char = p ^ 63;
136
+ char = (char & 0xaa) >> 1 | (char & 0x55) << 1;
137
+ char = (char & 0xcc) >> 2 | (char & 0x33) << 2;
138
+ char = char >> 4 | char << 4;
139
+ char = char >> 2 & 63;
140
+ switch(char){
141
+ case 0:
142
+ return ' ';
143
+ case 63:
144
+ return '\u2588';
145
+ case 21:
146
+ return '\u258C';
147
+ case 42:
148
+ return '\u2590';
149
+ default:
150
+ return String.fromCodePoint(0x1fb00 + char - 1 - (char > 21 ? 1 : 0) - (char > 42 ? 1 : 0));
151
+ }
152
+ };
153
+ const extent = Math.sqrt(data.byteLength) | 0;
154
+ const padded = extent + 2;
155
+ let output = '';
156
+ for(let baseRow = 0; baseRow < padded; baseRow += 3){
157
+ if (baseRow) output += '\n';
158
+ for(let baseCol = 0; baseCol < padded; baseCol += 2){
159
+ let p = 0;
160
+ for(let dr = 0; dr < 3; dr++){
161
+ for(let dc = 0; dc < 2; dc++){
162
+ const r = baseRow + dr;
163
+ const c = baseCol + dc;
164
+ const bit = 5 - (dr * 2 + dc);
165
+ let cell = 1; // default empty (out of bounds)
166
+ if (r < padded && c < padded) {
167
+ if (r === 0 || c === 0 || r === padded - 1 || c === padded - 1) {
168
+ cell = 0; // border is filled
169
+ } else if (r <= extent && c <= extent) {
170
+ cell = data[(r - 1) * extent + (c - 1)];
171
+ }
172
+ }
173
+ p |= (cell & 1) << bit;
174
+ }
175
+ }
176
+ output += getChar(p);
177
+ }
178
+ }
179
+ if (padded % 3 === 0) {
180
+ // Only add newline if the padded output lines up with a newline exactly
181
+ output += '\n';
182
+ }
183
+ return output;
184
+ }
185
+
186
+ //# sourceMappingURL=qr.js.map