"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