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.
235 lines
7.6 KiB
235 lines
7.6 KiB
"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
|