"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.determineEntryPointAsync = determineEntryPointAsync;
exports.extractAndInitializeTemplateApp = extractAndInitializeTemplateApp;
exports.extractTemplateAppAsync = extractTemplateAppAsync;
exports.saveRecentExpRootAsync = saveRecentExpRootAsync;
exports.expInfoSafeAsync = expInfoSafeAsync;
exports.getThirdPartyInfoAsync = getThirdPartyInfoAsync;
exports.getPublishInfoAsync = getPublishInfoAsync;
exports.recentValidExpsAsync = recentValidExpsAsync;
exports.sendAsync = sendAsync;
exports.getProjectRandomnessAsync = getProjectRandomnessAsync;
exports.resetProjectRandomnessAsync = resetProjectRandomnessAsync;
exports.clearXDLCacheAsync = clearXDLCacheAsync;
exports.ENTRY_POINT_PLATFORM_TEMPLATE_STRING = void 0;
function ConfigUtils() {
const data = _interopRequireWildcard(require("@expo/config"));
ConfigUtils = function () {
return data;
};
return data;
}
function _fsExtra() {
const data = _interopRequireDefault(require("fs-extra"));
_fsExtra = function () {
return data;
};
return data;
}
function _merge() {
const data = _interopRequireDefault(require("lodash/merge"));
_merge = function () {
return data;
};
return data;
}
function _path() {
const data = _interopRequireDefault(require("path"));
_path = function () {
return data;
};
return data;
}
function _spawnAsync() {
const data = _interopRequireDefault(require("@expo/spawn-async"));
_spawnAsync = function () {
return data;
};
return data;
}
function _jsonFile() {
const data = _interopRequireDefault(require("@expo/json-file"));
_jsonFile = function () {
return data;
};
return data;
}
function _minipass() {
const data = _interopRequireDefault(require("minipass"));
_minipass = function () {
return data;
};
return data;
}
function _pacote() {
const data = _interopRequireDefault(require("pacote"));
_pacote = function () {
return data;
};
return data;
}
function _tar() {
const data = _interopRequireDefault(require("tar"));
_tar = function () {
return data;
};
return data;
}
function _Api() {
const data = _interopRequireDefault(require("./Api"));
_Api = function () {
return data;
};
return data;
}
function _Logger() {
const data = _interopRequireDefault(require("./Logger"));
_Logger = function () {
return data;
};
return data;
}
function _NotificationCode() {
const data = _interopRequireDefault(require("./NotificationCode"));
_NotificationCode = function () {
return data;
};
return data;
}
function ThirdParty() {
const data = _interopRequireWildcard(require("./ThirdParty"));
ThirdParty = function () {
return data;
};
return data;
}
function _User() {
const data = _interopRequireDefault(require("./User"));
_User = function () {
return data;
};
return data;
}
function UrlUtils() {
const data = _interopRequireWildcard(require("./UrlUtils"));
UrlUtils = function () {
return data;
};
return data;
}
function _UserSettings() {
const data = _interopRequireDefault(require("./UserSettings"));
_UserSettings = function () {
return data;
};
return data;
}
function ProjectSettings() {
const data = _interopRequireWildcard(require("./ProjectSettings"));
ProjectSettings = function () {
return data;
};
return data;
}
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
// FIXME(perry) eliminate usage of this template
const ENTRY_POINT_PLATFORM_TEMPLATE_STRING = 'PLATFORM_GOES_HERE'; // TODO(ville): update when this has landed: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/36598
exports.ENTRY_POINT_PLATFORM_TEMPLATE_STRING = ENTRY_POINT_PLATFORM_TEMPLATE_STRING;
async function determineEntryPointAsync(root) {
let {
exp,
pkg
} = await ConfigUtils().readConfigJsonAsync(root); // entryPoint is relative to the packager root and main is relative
// to the project root. So if your rn-cli.config.js points to a different
// root than the project root, these can be different. Most of the time
// you should use main.
let entryPoint = pkg.main || 'index.js';
if (exp && exp.entryPoint) {
entryPoint = exp.entryPoint;
}
return entryPoint;
}
class Transformer extends _minipass().default {
constructor(config) {
super();
_defineProperty(this, "data", void 0);
_defineProperty(this, "config", void 0);
this.data = '';
this.config = config;
}
write(data) {
this.data += data;
return true;
}
end() {
let replaced = this.data.replace(/Hello App Display Name/g, this.config.displayName || this.config.name).replace(/HelloWorld/g, this.config.name).replace(/helloworld/g, this.config.name.toLowerCase());
super.write(replaced);
return super.end();
}
} // Binary files, don't process these (avoid decoding as utf8)
const binaryExtensions = ['.png', '.jar'];
function createFileTransform(config) {
return function transformFile(entry) {
if (!binaryExtensions.includes(_path().default.extname(entry.path)) && config.name) {
return new Transformer(config);
}
return;
};
}
async function extractAndInitializeTemplateApp(templateSpec, projectRoot, packageManager = 'npm', config) {
_Logger().default.notifications.info({
code: _NotificationCode().default.PROGRESS
}, 'Extracting project files...');
await extractTemplateAppAsync(templateSpec, projectRoot, config); // Update files
_Logger().default.notifications.info({
code: _NotificationCode().default.PROGRESS
}, 'Customizing project...');
let appFile = new (_jsonFile().default)(_path().default.join(projectRoot, 'app.json'));
let appJson = (0, _merge().default)((await appFile.readAsync()), config);
await appFile.writeAsync(appJson);
let packageFile = new (_jsonFile().default)(_path().default.join(projectRoot, 'package.json'));
let packageJson = await packageFile.readAsync(); // Adding `private` stops npm from complaining about missing `name` and `version` fields.
// We don't add a `name` field because it also exists in `app.json`.
packageJson = { ...packageJson,
private: true
}; // These are metadata fields related to the template package, let's remove them from the package.json.
delete packageJson.name;
delete packageJson.version;
delete packageJson.description;
delete packageJson.tags;
delete packageJson.repository; // pacote adds these, but we don't want them in the package.json of the project.
delete packageJson._resolved;
delete packageJson._integrity;
delete packageJson._from;
await packageFile.writeAsync(packageJson);
await initGitRepoAsync(projectRoot);
await installDependenciesAsync(projectRoot, packageManager);
return projectRoot;
}
async function extractTemplateAppAsync(templateSpec, targetPath, config) {
let tarStream = await _pacote().default.tarball.stream(templateSpec, {
cache: _path().default.join(_UserSettings().default.dotExpoHomeDirectory(), 'template-cache')
});
await _fsExtra().default.mkdirp(targetPath);
await new Promise((resolve, reject) => {
const extractStream = _tar().default.x({
cwd: targetPath,
strip: 1,
// TODO(ville): pending https://github.com/DefinitelyTyped/DefinitelyTyped/pull/36598
// @ts-ignore property missing from the type definition
transform: createFileTransform(config),
onentry(entry) {
if (config.name) {
// Rewrite paths for bare workflow
entry.path = entry.path.replace(/HelloWorld/g, config.name).replace(/helloworld/g, config.name.toLowerCase());
}
if (/^file$/i.test(entry.type) && _path().default.basename(entry.path) === 'gitignore') {
// Rename `gitignore` because npm ignores files named `.gitignore` when publishing.
// See: https://github.com/npm/npm/issues/1862
entry.path = entry.path.replace(/gitignore$/, '.gitignore');
}
}
});
tarStream.on('error', reject);
extractStream.on('error', reject);
extractStream.on('close', resolve);
tarStream.pipe(extractStream);
});
return targetPath;
}
async function initGitRepoAsync(root) {
// let's see if we're in a git tree
let insideGit = true;
try {
await (0, _spawnAsync().default)('git', ['rev-parse', '--is-inside-work-tree'], {
cwd: root
});
_Logger().default.global.debug('New project is already inside of a git repo, skipping git init.');
} catch (e) {
if (e.errno == 'ENOENT') {
_Logger().default.global.warn('Unable to initialize git repo. `git` not in PATH.');
}
insideGit = false;
}
if (!insideGit) {
try {
await (0, _spawnAsync().default)('git', ['init'], {
cwd: root
});
_Logger().default.global.info('Initialized a git repository.');
} catch (e) {// no-op -- this is just a convenience and we don't care if it fails
}
}
}
async function installDependenciesAsync(projectRoot, packageManager) {
_Logger().default.global.info('Installing dependencies...');
if (packageManager === 'yarn') {
await (0, _spawnAsync().default)('yarnpkg', ['install'], {
cwd: projectRoot,
stdio: 'inherit'
});
} else {
await (0, _spawnAsync().default)('npm', ['install'], {
cwd: projectRoot,
stdio: 'inherit'
});
}
}
async function saveRecentExpRootAsync(root) {
root = _path().default.resolve(root); // Write the recent Exps JSON file
const recentExpsJsonFile = _UserSettings().default.recentExpsJsonFile();
let recentExps = await recentExpsJsonFile.readAsync(); // Filter out copies of this so we don't get dupes in this list
recentExps = recentExps.filter(dir => dir !== root);
recentExps.unshift(root);
return await recentExpsJsonFile.writeAsync(recentExps.slice(0, 100));
}
function getHomeDir() {
return process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'] || '';
}
function makePathReadable(pth) {
let homedir = getHomeDir();
if (pth.substr(0, homedir.length) === homedir) {
return `~${pth.substr(homedir.length)}`;
} else {
return pth;
}
}
async function expInfoSafeAsync(root) {
try {
let {
exp: {
name,
description,
icon,
iconUrl
}
} = await ConfigUtils().readConfigJsonAsync(root);
let pathOrUrl = icon || iconUrl || 'https://d3lwq5rlu14cro.cloudfront.net/ExponentEmptyManifest_192.png';
let resolvedPath = _path().default.resolve(root, pathOrUrl);
if (_fsExtra().default.existsSync(resolvedPath)) {
icon = `file://${resolvedPath}`;
} else {
icon = pathOrUrl; // Assume already a URL
}
return {
readableRoot: makePathReadable(root),
root,
name,
description,
icon
};
} catch (e) {
return null;
}
}
async function getThirdPartyInfoAsync(publicUrl) {
const user = await _User().default.ensureLoggedInAsync();
if (!user) {
throw new Error('Attempted to login in offline mode. This is a bug.');
}
const {
username
} = user;
const exp = await ThirdParty().getManifest(publicUrl);
const {
slug,
sdkVersion,
version
} = exp;
if (!sdkVersion) {
throw new Error(`sdkVersion is missing from ${publicUrl}`);
}
if (!slug) {
// slug is made programmatically for app.json
throw new Error(`slug field is missing from exp.json.`);
}
if (!version) {
throw new Error(`Can't get version of package.`);
}
const iosBundleIdentifier = exp.ios ? exp.ios.bundleIdentifier : null;
const androidPackage = exp.android ? exp.android.package : null;
return {
args: {
username,
remoteUsername: username,
remotePackageName: slug,
remoteFullPackageName: `@${username}/${slug}`,
sdkVersion,
iosBundleIdentifier,
androidPackage
}
};
} // TODO: remove / change, no longer publishInfo, this is just used for signing
async function getPublishInfoAsync(root) {
const user = await _User().default.ensureLoggedInAsync();
if (!user) {
throw new Error('Attempted to login in offline mode. This is a bug.');
}
let {
username
} = user;
const {
exp
} = await ConfigUtils().readConfigJsonAsync(root);
const name = exp.slug;
const {
version,
sdkVersion
} = exp;
const configName = await ConfigUtils().configFilenameAsync(root);
if (!sdkVersion) {
throw new Error(`sdkVersion is missing from ${configName}`);
}
if (!name) {
// slug is made programmatically for app.json
throw new Error(`slug field is missing from exp.json.`);
}
if (!version) {
throw new Error(`Can't get version of package.`);
}
const remotePackageName = name;
const remoteUsername = username;
const remoteFullPackageName = `@${remoteUsername}/${remotePackageName}`;
const iosBundleIdentifier = exp.ios ? exp.ios.bundleIdentifier : null;
const androidPackage = exp.android ? exp.android.package : null;
return {
args: {
username,
remoteUsername,
remotePackageName,
remoteFullPackageName,
sdkVersion,
iosBundleIdentifier,
androidPackage
}
};
}
async function recentValidExpsAsync() {
let recentExpsJsonFile = _UserSettings().default.recentExpsJsonFile();
let recentExps = await recentExpsJsonFile.readAsync();
let results = await Promise.all(recentExps.map(expInfoSafeAsync));
let filteredResults = results.filter(result => result);
return filteredResults;
}
async function sendAsync(recipient, url_, allowUnauthed = true) {
let result = await _Api().default.callMethodAsync('send', [recipient, url_, allowUnauthed]);
return result;
} // TODO: figure out where these functions should live
async function getProjectRandomnessAsync(projectRoot) {
let ps = await ProjectSettings().readAsync(projectRoot);
let randomness = ps.urlRandomness;
if (randomness) {
return randomness;
} else {
return resetProjectRandomnessAsync(projectRoot);
}
}
async function resetProjectRandomnessAsync(projectRoot) {
let randomness = UrlUtils().someRandomness();
ProjectSettings().setAsync(projectRoot, {
urlRandomness: randomness
});
return randomness;
}
async function clearXDLCacheAsync() {
let dotExpoHomeDirectory = _UserSettings().default.dotExpoHomeDirectory();
_fsExtra().default.removeSync(_path().default.join(dotExpoHomeDirectory, 'ios-simulator-app-cache'));
_fsExtra().default.removeSync(_path().default.join(dotExpoHomeDirectory, 'android-apk-cache'));
_fsExtra().default.removeSync(_path().default.join(dotExpoHomeDirectory, 'starter-app-cache'));
_Logger().default.notifications.info(`Cleared cache`);
}
//# sourceMappingURL=__sourcemaps__/Exp.js.map