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.
379 lines
9.7 KiB
379 lines
9.7 KiB
'use strict';
|
|
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
|
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
|
|
|
var consola = _interopDefault(require('consola'));
|
|
var child_process = require('child_process');
|
|
var chalk = _interopDefault(require('chalk'));
|
|
var path = _interopDefault(require('path'));
|
|
var fs = _interopDefault(require('fs'));
|
|
var fetch = _interopDefault(require('node-fetch'));
|
|
|
|
const reportAndThrowError = msg => {
|
|
report(msg);
|
|
throw new Error(msg);
|
|
};
|
|
const report = message => {
|
|
consola.debug({
|
|
message: String(message),
|
|
tag: 'opencollective'
|
|
});
|
|
};
|
|
const hideMessage = (env = process.env) => {
|
|
// Show message if it is forced
|
|
if (env.OPENCOLLECTIVE_FORCE) {
|
|
return false;
|
|
} // Don't show after oracle postinstall
|
|
|
|
|
|
if (env.OC_POSTINSTALL_TEST) {
|
|
return true;
|
|
} // Don't show if opted-out
|
|
|
|
|
|
if (env.OPENCOLLECTIVE_HIDE) {
|
|
return true;
|
|
} // Don't show if on CI
|
|
|
|
|
|
if (env.CI || env.CONTINUOUS_INTEGRATION) {
|
|
return true;
|
|
} // Only show in dev environment
|
|
|
|
|
|
return Boolean(env.NODE_ENV) && !['dev', 'development'].includes(env.NODE_ENV);
|
|
};
|
|
const formatMoney = currency => amount => {
|
|
amount = amount / 100; // converting cents
|
|
|
|
const precision = 0;
|
|
return amount.toLocaleString(currency, {
|
|
style: 'currency',
|
|
currency: currency,
|
|
minimumFractionDigits: precision,
|
|
maximumFractionDigits: precision
|
|
});
|
|
};
|
|
const isWin32 = process.platform === 'win32';
|
|
const stripLeadingSlash = s => s.startsWith('/') ? s.substring(1) : s;
|
|
const stripTrailingSlash = s => s.endsWith('/') ? s.slice(0, -1) : s;
|
|
|
|
/* eslint-disable no-console */
|
|
const print = (color = null) => (str = '') => {
|
|
const terminalCols = retrieveCols();
|
|
const strLength = str.replace(/\u001b\[[0-9]{2}m/g, '').length;
|
|
const leftPaddingLength = Math.floor((terminalCols - strLength) / 2);
|
|
const leftPadding = ' '.repeat(Math.max(leftPaddingLength, 0));
|
|
|
|
if (color) {
|
|
str = chalk[color](str);
|
|
}
|
|
|
|
console.log(leftPadding, str);
|
|
};
|
|
const retrieveCols = (() => {
|
|
let result = false;
|
|
return () => {
|
|
if (result) {
|
|
return result;
|
|
}
|
|
|
|
const defaultCols = 80;
|
|
|
|
try {
|
|
const terminalCols = child_process.execSync(`tput cols`, {
|
|
stdio: ['pipe', 'pipe', 'ignore']
|
|
});
|
|
result = parseInt(terminalCols.toString()) || defaultCols;
|
|
} catch (e) {
|
|
result = defaultCols;
|
|
}
|
|
|
|
return result;
|
|
};
|
|
})();
|
|
const printStats = (stats, color) => {
|
|
if (!stats) {
|
|
return;
|
|
}
|
|
|
|
const colored = print(color);
|
|
const bold = print('bold');
|
|
const formatWithCurrency = formatMoney(stats.currency);
|
|
colored(`Number of contributors: ${stats.contributorsCount}`);
|
|
colored(`Number of backers: ${stats.backersCount}`);
|
|
colored(`Annual budget: ${formatWithCurrency(stats.yearlyIncome)}`);
|
|
bold(`Current balance: ${formatWithCurrency(stats.balance)}`, 'bold');
|
|
};
|
|
const printLogo = logoText => {
|
|
if (!logoText) {
|
|
return;
|
|
}
|
|
|
|
logoText.split('\n').forEach(print('blue'));
|
|
};
|
|
/**
|
|
* Only show emoji on OSx (Windows shell doesn't like them that much ¯\_(ツ)_/¯ )
|
|
* @param {*} emoji
|
|
*/
|
|
|
|
const emoji = emoji => process.stdout.isTTY && !isWin32 ? emoji : '';
|
|
function printFooter(collective) {
|
|
const dim = print('dim');
|
|
const yellow = print('yellow');
|
|
const emptyLine = print();
|
|
yellow(`Thanks for installing ${collective.slug} ${emoji('🙏')}`);
|
|
dim(`Please consider donating to our open collective`);
|
|
dim(`to help us maintain this package.`);
|
|
emptyLine();
|
|
printStats(collective.stats);
|
|
emptyLine();
|
|
print()(`${chalk.bold(`${emoji('👉 ')} ${collective.donationText}`)} ${chalk.underline(collective.donationUrl)}`);
|
|
emptyLine();
|
|
}
|
|
|
|
function _slicedToArray(arr, i) {
|
|
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
|
|
}
|
|
|
|
function _arrayWithHoles(arr) {
|
|
if (Array.isArray(arr)) return arr;
|
|
}
|
|
|
|
function _iterableToArrayLimit(arr, i) {
|
|
var _arr = [];
|
|
var _n = true;
|
|
var _d = false;
|
|
var _e = undefined;
|
|
|
|
try {
|
|
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
|
|
_arr.push(_s.value);
|
|
|
|
if (i && _arr.length === i) break;
|
|
}
|
|
} catch (err) {
|
|
_d = true;
|
|
_e = err;
|
|
} finally {
|
|
try {
|
|
if (!_n && _i["return"] != null) _i["return"]();
|
|
} finally {
|
|
if (_d) throw _e;
|
|
}
|
|
}
|
|
|
|
return _arr;
|
|
}
|
|
|
|
function _nonIterableRest() {
|
|
throw new TypeError("Invalid attempt to destructure non-iterable instance");
|
|
}
|
|
|
|
const FETCH_TIMEOUT = 3000;
|
|
|
|
const fetchJson = url => new Promise(function ($return, $error) {
|
|
var $Try_1_Post = function () {
|
|
try {
|
|
return $return();
|
|
} catch ($boundEx) {
|
|
return $error($boundEx);
|
|
}
|
|
};
|
|
|
|
var $Try_1_Catch = function (e) {
|
|
try {
|
|
report(e);
|
|
reportAndThrowError(`Could not fetch ${url}.json`);
|
|
return $Try_1_Post();
|
|
} catch ($boundEx) {
|
|
return $error($boundEx);
|
|
}
|
|
};
|
|
|
|
try {
|
|
return Promise.resolve(global.fetch(`${url}.json`, {
|
|
timeout: FETCH_TIMEOUT
|
|
})).then(function ($await_5) {
|
|
try {
|
|
return $return($await_5.json());
|
|
} catch ($boundEx) {
|
|
return $Try_1_Catch($boundEx);
|
|
}
|
|
}, $Try_1_Catch);
|
|
} catch (e) {
|
|
$Try_1_Catch(e);
|
|
}
|
|
});
|
|
|
|
const fetchStats = collectiveUrl$$1 => new Promise(function ($return, $error) {
|
|
var $Try_2_Post = function () {
|
|
try {
|
|
return $return();
|
|
} catch ($boundEx) {
|
|
return $error($boundEx);
|
|
}
|
|
};
|
|
|
|
var $Try_2_Catch = function (e) {
|
|
try {
|
|
report(e);
|
|
report(`Could not load the stats for ${collectiveSlugFromUrl(collectiveUrl$$1)}`);
|
|
return $Try_2_Post();
|
|
} catch ($boundEx) {
|
|
return $error($boundEx);
|
|
}
|
|
};
|
|
|
|
try {
|
|
return Promise.resolve(fetchJson(collectiveUrl$$1)).then($return, $Try_2_Catch);
|
|
} catch (e) {
|
|
$Try_2_Catch(e);
|
|
}
|
|
});
|
|
const fetchLogo = logoUrl => new Promise(function ($return, $error) {
|
|
if (!logoUrl) {
|
|
// Silent return if no logo has been provided
|
|
return $return();
|
|
}
|
|
|
|
if (!logoUrl.match(/^https?:\/\//)) {
|
|
reportAndThrowError(`Your logo URL isn't well-formatted - ${logoUrl}`);
|
|
}
|
|
|
|
var $Try_3_Post = function () {
|
|
try {
|
|
return $return();
|
|
} catch ($boundEx) {
|
|
return $error($boundEx);
|
|
}
|
|
};
|
|
|
|
var $Try_3_Catch = function (e) {
|
|
try {
|
|
report(`Error while fetching logo from ${logoUrl}`);
|
|
return $Try_3_Post();
|
|
} catch ($boundEx) {
|
|
return $error($boundEx);
|
|
}
|
|
};
|
|
|
|
try {
|
|
let res;
|
|
return Promise.resolve(global.fetch(logoUrl, {
|
|
timeout: FETCH_TIMEOUT
|
|
})).then(function ($await_7) {
|
|
try {
|
|
res = $await_7;
|
|
|
|
if (isLogoResponseWellFormatted(res)) {
|
|
return $return(res.text());
|
|
}
|
|
|
|
report(`Error while fetching logo from ${logoUrl}. The response wasn't well-formatted`);
|
|
return $Try_3_Post();
|
|
} catch ($boundEx) {
|
|
return $Try_3_Catch($boundEx);
|
|
}
|
|
}, $Try_3_Catch);
|
|
} catch (e) {
|
|
$Try_3_Catch(e);
|
|
}
|
|
});
|
|
|
|
const isLogoResponseWellFormatted = res => res.status === 200 && res.headers.get('content-type').match(/^text\/plain/);
|
|
|
|
const fetchPkg = pathToPkg => {
|
|
const fullPathToPkg = path.resolve(`${pathToPkg}/package.json`);
|
|
|
|
try {
|
|
return JSON.parse(fs.readFileSync(fullPathToPkg, 'utf8'));
|
|
} catch (e) {
|
|
reportAndThrowError(`Could not find package.json at ${fullPathToPkg}`);
|
|
}
|
|
};
|
|
|
|
const collectiveSlugFromUrl = url => url.substr(url.lastIndexOf('/') + 1).toLowerCase().replace(/\.json/g, '');
|
|
const collectiveUrl = pkg => {
|
|
const url = pkg.collective && pkg.collective.url;
|
|
|
|
if (!url) {
|
|
reportAndThrowError('No collective URL set!');
|
|
}
|
|
|
|
return stripTrailingSlash(url);
|
|
}; // use pkg.collective.logo for "legacy"/compatibility reasons
|
|
|
|
const collectiveLogoUrl = pkg => pkg.collective.logo || pkg.collective.logoUrl || false;
|
|
const collectiveDonationText = pkg => pkg.collective.donation && pkg.collective.donation.text || 'Donate:';
|
|
const getCollective = pkgPath => new Promise(function ($return, $error) {
|
|
let pkg, url, baseCollective, logoUrl, promises, _ref, _ref2, stats, logo;
|
|
|
|
pkg = fetchPkg(pkgPath);
|
|
url = collectiveUrl(pkg);
|
|
baseCollective = {
|
|
url,
|
|
slug: collectiveSlugFromUrl(url),
|
|
logoUrl: collectiveLogoUrl(pkg),
|
|
donationUrl: collectiveDonationUrl(pkg),
|
|
donationText: collectiveDonationText(pkg)
|
|
};
|
|
logoUrl = baseCollective.logoUrl;
|
|
promises = [fetchStats(url)].concat(logoUrl ? fetchLogo(logoUrl) : []);
|
|
return Promise.resolve(Promise.all(promises)).then(function ($await_1) {
|
|
try {
|
|
_ref = $await_1, _ref2 = _slicedToArray(_ref, 2), stats = _ref2[0], logo = _ref2[1];
|
|
return $return(Object.assign(baseCollective, {
|
|
stats,
|
|
logo
|
|
}));
|
|
} catch ($boundEx) {
|
|
return $error($boundEx);
|
|
}
|
|
}, $error);
|
|
});
|
|
const collectiveDonationUrl = pkg => {
|
|
const defaultDonationAmount = pkg.collective.donation && pkg.collective.donation.amount;
|
|
let donateUrl = `${collectiveUrl(pkg)}/${retrieveDonationSlug(pkg)}`;
|
|
|
|
if (defaultDonationAmount) {
|
|
return `${donateUrl}/${defaultDonationAmount}`;
|
|
}
|
|
|
|
return donateUrl;
|
|
};
|
|
const retrieveDonationSlug = pkg => {
|
|
const rawDonationSlug = pkg.collective.donation && pkg.collective.donation.slug;
|
|
|
|
if (!rawDonationSlug) {
|
|
return 'donate';
|
|
}
|
|
|
|
return stripLeadingSlash(rawDonationSlug);
|
|
};
|
|
|
|
function init(path$$1, hide = hideMessage()) {
|
|
return new Promise(function ($return, $error) {
|
|
let collective;
|
|
|
|
if (hide) {
|
|
return $return();
|
|
}
|
|
|
|
global.fetch = global.fetch || fetch;
|
|
return Promise.resolve(getCollective(path$$1)).then(function ($await_1) {
|
|
try {
|
|
collective = $await_1;
|
|
printLogo(collective.logo);
|
|
printFooter(collective);
|
|
return $return();
|
|
} catch ($boundEx) {
|
|
return $error($boundEx);
|
|
}
|
|
}, $error);
|
|
});
|
|
}
|
|
|
|
exports.init = init;
|
|
|