"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dotExpoProjectDirectory = dotExpoProjectDirectory; exports.dotExpoProjectDirectoryExists = dotExpoProjectDirectoryExists; exports.getCurrentStatusAsync = getCurrentStatusAsync; exports.getDevicesInfoAsync = getDevicesInfoAsync; exports.readAsync = readAsync; exports.readDevicesInfoAsync = readDevicesInfoAsync; exports.readPackagerInfoAsync = readPackagerInfoAsync; exports.saveDevicesAsync = saveDevicesAsync; exports.setAsync = setAsync; exports.setDevicesInfoAsync = setDevicesInfoAsync; exports.setPackagerInfoAsync = setPackagerInfoAsync; function _jsonFile() { const data = _interopRequireDefault(require("@expo/json-file")); _jsonFile = function () { return data; }; return data; } function _fsExtra() { const data = _interopRequireDefault(require("fs-extra")); _fsExtra = 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 }; } const projectSettingsFile = 'settings.json'; const projectSettingsDefaults = { scheme: null, hostType: 'lan', lanType: 'ip', devClient: false, dev: true, minify: false, urlRandomness: null, https: false, strict: undefined }; const packagerInfoFile = 'packager-info.json'; const devicesFile = 'devices.json'; const MILLISECONDS_IN_30_DAYS = 30 * 24 * 60 * 60 * 1000; function projectSettingsJsonFile(projectRoot) { return new (_jsonFile().default)(_path().default.join(dotExpoProjectDirectory(projectRoot), projectSettingsFile)); } function packagerInfoJsonFile(projectRoot) { return new (_jsonFile().default)(_path().default.join(dotExpoProjectDirectory(projectRoot), packagerInfoFile)); } function devicesJsonFile(projectRoot) { return new (_jsonFile().default)(_path().default.join(dotExpoProjectDirectory(projectRoot), devicesFile)); } async function readAsync(projectRoot) { let projectSettings; try { projectSettings = await projectSettingsJsonFile(projectRoot).readAsync(); } catch { projectSettings = await projectSettingsJsonFile(projectRoot).writeAsync(projectSettingsDefaults); } migrateDeprecatedSettings(projectSettings); // Set defaults for any missing fields return { ...projectSettingsDefaults, ...projectSettings }; } function migrateDeprecatedSettings(projectSettings) { if (projectSettings.hostType === 'ngrok') { // 'ngrok' is deprecated projectSettings.hostType = 'tunnel'; } if (projectSettings.urlType) { // urlType is deprecated as a project setting delete projectSettings.urlType; } if ('strict' in projectSettings) { // strict mode is not supported at the moment delete projectSettings.strict; } } async function setAsync(projectRoot, json) { try { return await projectSettingsJsonFile(projectRoot).mergeAsync(json, { cantReadFileDefault: projectSettingsDefaults }); } catch { return await projectSettingsJsonFile(projectRoot).writeAsync({ ...projectSettingsDefaults, ...json }); } } async function readPackagerInfoAsync(projectRoot) { try { return await packagerInfoJsonFile(projectRoot).readAsync({ cantReadFileDefault: {} }); } catch { return await packagerInfoJsonFile(projectRoot).writeAsync({}); } } async function getCurrentStatusAsync(projectRoot) { const { packagerPort, expoServerPort } = await readPackagerInfoAsync(projectRoot); if (packagerPort && expoServerPort) { return 'running'; } else if (packagerPort || expoServerPort) { return 'ill'; } else { return 'exited'; } } async function setPackagerInfoAsync(projectRoot, json) { try { return await packagerInfoJsonFile(projectRoot).mergeAsync(json, { cantReadFileDefault: {} }); } catch { return await packagerInfoJsonFile(projectRoot).writeAsync(json); } } let devicesInfo = null; async function getDevicesInfoAsync(projectRoot) { if (devicesInfo) { return devicesInfo; } return readDevicesInfoAsync(projectRoot); } async function readDevicesInfoAsync(projectRoot) { try { devicesInfo = await devicesJsonFile(projectRoot).readAsync({ cantReadFileDefault: { devices: [] } }); // if the file on disk has old devices, filter them out here before we use them const filteredDevices = filterOldDevices(devicesInfo.devices); if (filteredDevices.length < devicesInfo.devices.length) { devicesInfo = { ...devicesInfo, devices: filteredDevices }; // save the newly filtered list for consistency try { await setDevicesInfoAsync(projectRoot, devicesInfo); } catch { // do nothing here, we'll just keep using the filtered list in memory for now } } return devicesInfo; } catch { return await devicesJsonFile(projectRoot).writeAsync({ devices: [] }); } } async function setDevicesInfoAsync(projectRoot, json) { devicesInfo = json; try { return await devicesJsonFile(projectRoot).mergeAsync(json, { cantReadFileDefault: { devices: [] } }); } catch { return await devicesJsonFile(projectRoot).writeAsync(json); } } async function saveDevicesAsync(projectRoot, deviceIds) { const currentTime = new Date().getTime(); const newDeviceIds = typeof deviceIds === 'string' ? [deviceIds] : deviceIds; const { devices } = await getDevicesInfoAsync(projectRoot); const newDevicesJson = devices.filter(device => { if (newDeviceIds.includes(device.installationId)) { return false; } return true; }).concat(newDeviceIds.map(deviceId => ({ installationId: deviceId, lastUsed: currentTime }))); await setDevicesInfoAsync(projectRoot, { devices: filterOldDevices(newDevicesJson) }); } function filterOldDevices(devices) { const currentTime = new Date().getTime(); return devices.filter(device => { // filter out any devices that haven't been used to open this project in 30 days if (currentTime - device.lastUsed > MILLISECONDS_IN_30_DAYS) { return false; } return true; }) // keep only the 10 most recently used devices .sort((a, b) => b.lastUsed - a.lastUsed).slice(0, 10); } function dotExpoProjectDirectory(projectRoot) { const dirPath = _path().default.join(projectRoot, '.expo'); try { // move .exponent to .expo const oldDirPath = _path().default.join(projectRoot, '.exponent'); if (_fsExtra().default.statSync(oldDirPath).isDirectory()) { _fsExtra().default.renameSync(oldDirPath, dirPath); } } catch { // no old directory, continue } _fsExtra().default.mkdirpSync(dirPath); const readmeFilePath = _path().default.resolve(dirPath, 'README.md'); if (!_fsExtra().default.existsSync(readmeFilePath)) { _fsExtra().default.writeFileSync(readmeFilePath, `> Why do I have a folder named ".expo" in my project? The ".expo" folder is created when an Expo project is started using "expo start" command. > What do the files contain? - "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds. - "packager-info.json": contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator. - "settings.json": contains the server configuration that is used to serve the application manifest. > Should I commit the ".expo" folder? No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine. Upon project creation, the ".expo" folder is already added to your ".gitignore" file. `); } return dirPath; } function dotExpoProjectDirectoryExists(projectRoot) { const dirPath = _path().default.join(projectRoot, '.expo'); try { if (_fsExtra().default.statSync(dirPath).isDirectory()) { return true; } } catch { // file doesn't exist } return false; } //# sourceMappingURL=ProjectSettings.js.map