"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getManifestHandler = getManifestHandler; exports.getManifestResponseAsync = getManifestResponseAsync; function _config() { const data = require("@expo/config"); _config = function () { return data; }; return data; } function _configPlugins() { const data = require("@expo/config-plugins"); _configPlugins = function () { return data; }; return data; } function _chalk() { const data = _interopRequireDefault(require("chalk")); _chalk = function () { return data; }; return data; } function _nullthrows() { const data = _interopRequireDefault(require("nullthrows")); _nullthrows = function () { return data; }; return data; } function _url() { const data = require("url"); _url = function () { return data; }; return data; } function _uuid() { const data = require("uuid"); _uuid = function () { return data; }; return data; } function _internal() { const data = require("../internal"); _internal = function () { return data; }; return data; } function _ManifestHandler() { const data = require("./ManifestHandler"); _ManifestHandler = function () { return data; }; return data; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function getPlatformFromRequest(req) { const url = req.url ? (0, _url().parse)(req.url, /* parseQueryString */true) : null; const platform = (url === null || url === void 0 ? void 0 : url.query.platform) || req.headers['expo-platform']; if (!platform) { throw new Error('Must specify expo-platform header or query parameter'); } const stringifiedPlatform = String(platform); if (!['android', 'ios'].includes(stringifiedPlatform)) { throw new Error(`platform must be "android" or "ios". Recieved: "${platform}"`); } return stringifiedPlatform; } /** * Whether an anonymous scope key should be used. It should be used when: * 1. Offline * 2. Not logged-in * 3. No EAS project ID in config */ async function shouldUseAnonymousManifestAsync(easProjectId) { if (!easProjectId || _internal().ConnectionStatus.isOffline()) { return true; } const currentSession = await _internal().UserManager.getSessionAsync(); if (!currentSession) { return true; } return false; } async function getScopeKeyForProjectIdAsync(projectId) { const user = await _internal().UserManager.ensureLoggedInAsync(); const project = await _internal().ApiV2.clientForUser(user).getAsync(`projects/${encodeURIComponent(projectId)}`); return project.scopeKey; } async function signManifestAsync(manifest) { const user = await _internal().UserManager.ensureLoggedInAsync(); const { signature } = await _internal().ApiV2.clientForUser(user).postAsync('manifest/eas/sign', { manifest: manifest }); return signature; } async function getManifestResponseAsync({ projectRoot, platform, host, acceptSignature }) { var _expoConfig$runtimeVe, _expoConfig$extra, _expoConfig$extra$eas; const headers = new Map(); // set required headers for Expo Updates manifest specification headers.set('expo-protocol-version', 0); headers.set('expo-sfv-version', 0); headers.set('cache-control', 'private, max-age=0'); headers.set('content-type', 'application/json'); const hostname = (0, _ManifestHandler().stripPort)(host); const [projectSettings, bundleUrlPackagerOpts] = await (0, _ManifestHandler().getPackagerOptionsAsync)(projectRoot); const projectConfig = (0, _config().getConfig)(projectRoot); const entryPoint = (0, _internal().resolveEntryPoint)(projectRoot, platform, projectConfig); const mainModuleName = _internal().UrlUtils.stripJSExtension(entryPoint); const expoConfig = projectConfig.exp; const expoGoConfig = await (0, _ManifestHandler().getExpoGoConfig)({ projectRoot, projectSettings, mainModuleName, hostname }); const hostUri = await _internal().UrlUtils.constructHostUriAsync(projectRoot, hostname); const runtimeVersion = _configPlugins().Updates.getRuntimeVersion({ ...expoConfig, runtimeVersion: (_expoConfig$runtimeVe = expoConfig.runtimeVersion) !== null && _expoConfig$runtimeVe !== void 0 ? _expoConfig$runtimeVe : { policy: 'sdkVersion' } }, platform); if (!runtimeVersion) { throw new Error(`Unable to determine runtime version for ${platform}`); } const bundleUrl = await (0, _ManifestHandler().getBundleUrlAsync)({ projectRoot, platform, projectSettings, bundleUrlPackagerOpts, mainModuleName, hostname }); await _internal().ProjectAssets.resolveManifestAssets({ projectRoot, manifest: expoConfig, async resolver(path) { return bundleUrl.match(/^https?:\/\/.*?\//)[0] + 'assets/' + path; } }); const easProjectId = (_expoConfig$extra = expoConfig.extra) === null || _expoConfig$extra === void 0 ? void 0 : (_expoConfig$extra$eas = _expoConfig$extra.eas) === null || _expoConfig$extra$eas === void 0 ? void 0 : _expoConfig$extra$eas.projectId; const shouldUseAnonymousManifest = await shouldUseAnonymousManifestAsync(easProjectId); const userAnonymousIdentifier = await _internal().UserSettings.getAnonymousIdentifierAsync(); const scopeKey = shouldUseAnonymousManifest ? `@${_internal().ANONYMOUS_USERNAME}/${expoConfig.slug}-${userAnonymousIdentifier}` : await getScopeKeyForProjectIdAsync((0, _nullthrows().default)(easProjectId)); const expoUpdatesManifest = { id: (0, _uuid().v4)(), createdAt: new Date().toISOString(), runtimeVersion, launchAsset: { key: 'bundle', contentType: 'application/javascript', url: bundleUrl }, assets: [], // assets are not used in development metadata: {}, // required for the client to detect that this is an expo-updates manifest extra: { eas: { projectId: easProjectId !== null && easProjectId !== void 0 ? easProjectId : undefined }, expoClient: { ...expoConfig, hostUri }, expoGo: expoGoConfig, scopeKey } }; if (acceptSignature && !shouldUseAnonymousManifest) { const manifestSignature = await signManifestAsync(expoUpdatesManifest); headers.set('expo-manifest-signature', manifestSignature); } return { body: expoUpdatesManifest, headers }; } function getManifestHandler(projectRoot) { return async (req, res, next) => { // Only support `/`, `/manifest`, `/index.exp` for the manifest middleware. if (!req.url || !['/', '/manifest', '/index.exp'].includes( // Strip the query params (0, _url().parse)(req.url).pathname || req.url)) { next(); return; } if (_internal().Env.isDebug()) { console.log(_chalk().default.gray(`Manifest request: URL "${req.url}", Headers ${JSON.stringify(req.headers)}`)); } try { const { body, headers } = await getManifestResponseAsync({ projectRoot, host: req.headers.host, platform: getPlatformFromRequest(req), acceptSignature: !!req.headers['expo-accept-signature'] }); for (const [headerName, headerValue] of headers) { res.setHeader(headerName, headerValue); } res.end(JSON.stringify(body)); _internal().Analytics.logEvent('Serve Expo Updates Manifest', { developerTool: _internal().Config.developerTool, runtimeVersion: body.runtimeVersion }); } catch (e) { _internal().ProjectUtils.logError(projectRoot, 'expo', e.stack); res.statusCode = 520; res.end(JSON.stringify({ error: e.toString() })); } }; } //# sourceMappingURL=ExpoUpdatesManifestHandler.js.map