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.
205 lines
6.7 KiB
205 lines
6.7 KiB
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.downloadAndExtractNpmModuleAsync = downloadAndExtractNpmModuleAsync;
|
|
exports.extractLocalNpmTarballAsync = extractLocalNpmTarballAsync;
|
|
exports.extractNpmTarballAsync = extractNpmTarballAsync;
|
|
exports.extractNpmTarballFromUrlAsync = extractNpmTarballFromUrlAsync;
|
|
exports.npmPackAsync = npmPackAsync;
|
|
exports.sanitizeNpmPackageName = sanitizeNpmPackageName;
|
|
function _spawnAsync() {
|
|
const data = _interopRequireDefault(require("@expo/spawn-async"));
|
|
_spawnAsync = 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 _slugify() {
|
|
const data = _interopRequireDefault(require("slugify"));
|
|
_slugify = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _stream() {
|
|
const data = require("stream");
|
|
_stream = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _tar() {
|
|
const data = _interopRequireDefault(require("tar"));
|
|
_tar = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _util() {
|
|
const data = require("util");
|
|
_util = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _xdl() {
|
|
const data = require("xdl");
|
|
_xdl = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _log() {
|
|
const data = _interopRequireDefault(require("../../log"));
|
|
_log = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _createFileTransform() {
|
|
const data = require("./createFileTransform");
|
|
_createFileTransform = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _FileSystemCache() {
|
|
const data = require("./fetch-cache/FileSystemCache");
|
|
_FileSystemCache = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _fetch() {
|
|
const data = _interopRequireDefault(require("./fetch-cache/fetch"));
|
|
_fetch = function () {
|
|
return data;
|
|
};
|
|
return data;
|
|
}
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
const cachedFetch = (0, _fetch().default)(new (_FileSystemCache().FileSystemCache)({
|
|
cacheDirectory: getCacheFilePath()
|
|
// Time to live. How long (in ms) responses remain cached before being automatically ejected. If undefined, responses are never automatically ejected from the cache.
|
|
// ttl: 1000,
|
|
}));
|
|
|
|
function sanitizeNpmPackageName(name) {
|
|
// https://github.com/npm/validate-npm-package-name/#naming-rules
|
|
return applyKnownNpmPackageNameRules(name) || applyKnownNpmPackageNameRules((0, _slugify().default)(name)) ||
|
|
// If nothing is left use 'app' like we do in Xcode projects.
|
|
'app';
|
|
}
|
|
function applyKnownNpmPackageNameRules(name) {
|
|
// https://github.com/npm/validate-npm-package-name/#naming-rules
|
|
|
|
// package name cannot start with '.' or '_'.
|
|
while (/^(\.|_)/.test(name)) {
|
|
name = name.substring(1);
|
|
}
|
|
name = name.toLowerCase().replace(/[^a-zA-Z0-9._\-/@]/g, '');
|
|
return name
|
|
// .replace(/![a-z0-9-._~]+/g, '')
|
|
// Remove special characters
|
|
.normalize('NFD').replace(/[\u0300-\u036f]/g, '') || null;
|
|
}
|
|
async function npmPackAsync(packageName, cwd = undefined, ...props) {
|
|
var _await$spawnAsync$std;
|
|
const cmd = ['pack', packageName, ...props];
|
|
const cmdString = `npm ${cmd.join(' ')}`;
|
|
_log().default.debug('Run:', cmdString);
|
|
const results = (_await$spawnAsync$std = (await (0, _spawnAsync().default)('npm', [...cmd, '--json'], {
|
|
cwd
|
|
})).stdout) === null || _await$spawnAsync$std === void 0 ? void 0 : _await$spawnAsync$std.trim();
|
|
if (!results) {
|
|
return null;
|
|
}
|
|
try {
|
|
const parsedResults = JSON.parse(results);
|
|
const filename = parsedResults[0].filename;
|
|
|
|
// Transform filename for scoped packages.
|
|
// See issue https://github.com/npm/cli/issues/3405
|
|
if (filename !== null && filename !== void 0 && filename.startsWith('@') && packageName.startsWith('@')) {
|
|
parsedResults[0].filename = filename.replace(/^@/, '').replace(/\//, '-');
|
|
}
|
|
return parsedResults;
|
|
} catch (error) {
|
|
throw new Error(`Could not parse JSON returned from "${cmdString}".\n\n${results}\n\nError: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
// @ts-ignore
|
|
const pipeline = (0, _util().promisify)(_stream().Stream.pipeline);
|
|
async function downloadAndExtractNpmModuleAsync(npmName, props) {
|
|
_log().default.debug(`Looking for tarball for ${npmName} in ${getCacheFilePath()}...`);
|
|
try {
|
|
var _await$fs$stat$catch$, _await$fs$stat$catch;
|
|
const cachePath = getCacheFilePath();
|
|
await _fsExtra().default.ensureDir(cachePath);
|
|
// Perform dry-run to get actual filename for resolved version
|
|
const filename = (await npmPackAsync(npmName, cachePath, '--dry-run'))[0].filename;
|
|
const cacheFilename = _path().default.join(cachePath, filename);
|
|
|
|
// TODO: This cache does not expire, but neither does the FileCache at the top of this file.
|
|
if ((_await$fs$stat$catch$ = !((_await$fs$stat$catch = await _fsExtra().default.stat(cacheFilename).catch(() => null)) !== null && _await$fs$stat$catch !== void 0 && _await$fs$stat$catch.isFile())) !== null && _await$fs$stat$catch$ !== void 0 ? _await$fs$stat$catch$ : false) {
|
|
_log().default.debug(`Downloading tarball for ${npmName} to ${cachePath}...`);
|
|
await npmPackAsync(npmName, cachePath);
|
|
}
|
|
await extractLocalNpmTarballAsync(cacheFilename, {
|
|
cwd: props.cwd,
|
|
name: props.name
|
|
});
|
|
} catch (error) {
|
|
_log().default.error('Error downloading and extracting template package:', error);
|
|
}
|
|
}
|
|
async function extractLocalNpmTarballAsync(tarFilePath, props) {
|
|
const readStream = _fsExtra().default.createReadStream(tarFilePath);
|
|
await extractNpmTarballAsync(readStream, props);
|
|
}
|
|
function getCacheFilePath() {
|
|
return _path().default.join(_xdl().UserSettings.dotExpoHomeDirectory(), 'template-cache');
|
|
}
|
|
async function createUrlStreamAsync(url) {
|
|
const response = await cachedFetch(url);
|
|
if (!response.ok) {
|
|
throw new Error(`Unexpected response: ${response.statusText}. From url: ${url}`);
|
|
}
|
|
return response.body;
|
|
}
|
|
async function extractNpmTarballFromUrlAsync(url, props) {
|
|
await extractNpmTarballAsync(await createUrlStreamAsync(url), props);
|
|
}
|
|
async function extractNpmTarballAsync(stream, props) {
|
|
const {
|
|
cwd,
|
|
strip,
|
|
name,
|
|
fileList = []
|
|
} = props;
|
|
await _fsExtra().default.ensureDir(cwd);
|
|
return pipeline(stream, _tar().default.extract({
|
|
cwd,
|
|
transform: (0, _createFileTransform().createFileTransform)(name),
|
|
onentry: (0, _createFileTransform().createEntryResolver)(name),
|
|
strip: strip !== null && strip !== void 0 ? strip : 1
|
|
}, fileList));
|
|
}
|
|
//# sourceMappingURL=npm.js.map
|