You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
257 lines
8.1 KiB
257 lines
8.1 KiB
"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
|