@salesforce/templates
Version:
Salesforce JS library for templates
122 lines • 5.49 kB
JavaScript
/* eslint header/header: off */
/*---------------------------------------------------------------------------------------------
* Copyright (c) 2021 Vercel, Inc. All rights reserved.
* Licensed under the MIT License. See OSSREADME.json in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadCustomTemplatesGitRepo = exports.getStoragePathForCustomTemplates = exports.getRepoInfo = exports.DIR = void 0;
const tslib_1 = require("tslib");
/**
* The following implementation are adapted from create-next-app
* See https://github.com/vercel/next.js for more information
*/
const crypto = require("crypto");
const fs = require("fs");
const got_1 = require("got");
const path = require("path");
const stream_1 = require("stream");
const tar = require("tar");
const os = require("node:os");
const util_1 = require("util");
const i18n_1 = require("../i18n");
const hpagent_1 = require("hpagent");
const proxy_from_env_1 = require("proxy-from-env");
const SFDX_STATE_FOLDER = '.sfdx';
/**
* The full system path to the preferred global state folder
*/
function DIR() {
return path.join(os.homedir(), SFDX_STATE_FOLDER);
}
exports.DIR = DIR;
/**
* extract repo info from uri
* @param repoUri uri to git repo
*/
function getRepoInfo(repoUri) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const [, username, name, t, branch, ...file] = repoUri.pathname.split('/');
const filePath = `${file.join('/')}`;
// For repos with no branch information, fetch default branch
if (t === undefined) {
const url = `https://api.github.com/repos/${username}/${name}`;
const proxy = (0, proxy_from_env_1.getProxyForUrl)(url);
// proxy will be empty string if no proxy is set
const infoResponse = yield (proxy !== ''
? (0, got_1.default)(url, {
agent: {
https: new hpagent_1.HttpsProxyAgent({
keepAlive: true,
keepAliveMsecs: 1000,
maxSockets: 256,
maxFreeSockets: 256,
scheduling: 'lifo',
proxy,
}),
},
})
: (0, got_1.default)(url)).catch((e) => e);
if (infoResponse.statusCode !== 200) {
throw new Error(i18n_1.nls.localize('customTemplatesCannotRetrieveDefaultBranch', repoUri.href));
}
const info = JSON.parse(infoResponse.body);
return { username, name, branch: info['default_branch'], filePath };
}
if (username && name && branch && t === 'tree') {
return { username, name, branch, filePath };
}
else {
throw new Error(i18n_1.nls.localize('customTemplatesInvalidRepoUrl', repoUri.href));
}
});
}
exports.getRepoInfo = getRepoInfo;
/**
* Returns a path to store custom templates from a Git repo
* @param repoUri repository uri
* @returns path to store custom templates
*/
function getStoragePathForCustomTemplates(repoUri) {
const folderHash = crypto
.createHash('md5')
.update(repoUri.href)
.digest('hex');
const customTemplatesPath = path.join(DIR(), 'custom-templates', folderHash);
return customTemplatesPath;
}
exports.getStoragePathForCustomTemplates = getStoragePathForCustomTemplates;
/**
* Load custom templates Git repo. Currently only supports GitHub.
* @param repoUri repo uri
* @param forceLoadingRemoteRepo by default do not reload remote repo if the repo is already downloaded
* @returns path to the local storage location of the repo
*/
function loadCustomTemplatesGitRepo(repoUri_1) {
return tslib_1.__awaiter(this, arguments, void 0, function* (repoUri, forceLoadingRemoteRepo = false) {
const customTemplatesPath = getStoragePathForCustomTemplates(repoUri);
// Do not load the remote repo if already the repo is already downloaded.
if (fs.existsSync(customTemplatesPath) && !forceLoadingRemoteRepo) {
return customTemplatesPath;
}
if (repoUri.protocol !== 'https:') {
throw new Error(i18n_1.nls.localize('customTemplatesShouldUseHttpsProtocol', `"${repoUri.protocol}"`));
}
if (repoUri.hostname !== 'github.com') {
throw new Error(i18n_1.nls.localize('customTemplatesSupportsGitHubOnly', repoUri.href));
}
const { username, name, branch, filePath } = yield getRepoInfo(repoUri);
if (!fs.existsSync(customTemplatesPath)) {
fs.mkdirSync(customTemplatesPath, { recursive: true });
}
// Download the repo and extract to the SFDX global state folder
const pipeline = (0, util_1.promisify)(stream_1.Stream.pipeline);
yield pipeline(got_1.default.stream(`https://codeload.github.com/${username}/${name}/tar.gz/${branch}`), tar.extract({
cwd: customTemplatesPath,
strip: filePath ? filePath.split('/').length + 1 : 1,
}, [`${name}-${branch}${filePath ? `/${filePath}` : ''}`]));
return customTemplatesPath;
});
}
exports.loadCustomTemplatesGitRepo = loadCustomTemplatesGitRepo;
//# sourceMappingURL=gitRepoUtils.js.map
;