simplr-gulp
Version:
Fully functional gulpfile.js implementation. Tailored for Single Page Application. Written in TypeScript.
342 lines (341 loc) • 17.1 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");
const fs = require("fs");
const https = require("https");
const url = require("url");
const paths_1 = require("../../paths/paths");
const logger_1 = require("../../utils/logger");
const jspm = require("jspm");
const CDN_API = {
Hostname: "api.cdnjs.com",
Pathname: "libraries",
Query: { fields: "assets,version", search: undefined }
};
class JspmCdnPathsBuilder {
Start(done) {
return __awaiter(this, void 0, void 0, function* () {
let packagesList = this.getPackagesList();
let results = yield this.startDownload(packagesList);
if (results != null && Object.keys(results).length !== 0) {
yield this.saveResultToFile(results.Paths);
}
this.printResults(results);
done();
});
}
printResults(results) {
let logger = logger_1.LoggerInstance.withType("JSPM");
if (results.Resolved.length > 0) {
logger.info([`Successfully resolved ${results.Resolved.length} path${(results.Resolved.length > 1) ? "s" : ""}:`]
.concat(results.Resolved.map((item, index) => {
return `${this.resultPrefix(index, results.Resolved.length)} ${item.FullName}: '${results.Paths[item.FullName]}'`;
}))
.join("\r\n"));
}
if (results.Unresolved.length > 0) {
logger.warn([`Failed to resolved ${results.Unresolved.length} path${(results.Unresolved.length > 1) ? "s" : ""}:`]
.concat(results.Unresolved.map((item, index) => {
return `${this.resultPrefix(index, results.Unresolved.length)} ${item.FullName}`;
}))
.join("\r\n"));
}
}
resultPrefix(index, itemsLength) {
return `\t\t\t ${(index === itemsLength - 1) ? "└─" : "├─"}`;
}
saveResultToFile(paths) {
return __awaiter(this, void 0, void 0, function* () {
let logger = logger_1.LoggerInstance.withType("JSPM");
return new Promise(resolve => {
let pathname = [paths_1.Paths.Directories.Source, "configs", "jspm.config.production.js"].join("/");
logger.info(`Generating file '${pathname}'`);
let data = [
"/* Generated by simplr-gulp */",
"SystemJS.config({",
" paths: " + JSON.stringify(paths, null, 4),
"});"
].join("\r\n");
fs.writeFile(pathname, data, (err) => {
if (err) {
logger.error(err.message);
}
resolve();
});
});
});
}
startDownload(packagesList, results = { Resolved: [], Unresolved: [], Paths: {} }) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
if (packagesList.length > 0) {
let item = packagesList.shift();
let cdnLink = yield this.getCdnLink(item);
if (cdnLink !== undefined) {
results.Resolved.push(item);
results.Paths[item.FullName] = cdnLink.replace(/^https?\:/i, "");
}
else {
results.Unresolved.push(item);
}
resolve(yield this.startDownload(packagesList, results));
}
else {
resolve(results);
}
}));
});
}
getCdnLink(packageItem, splited = false) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise(resolve => {
let logger = logger_1.LoggerInstance.withType(`JSPM [${packageItem.FullName}]`);
let requestDetails = {
protocol: "https:",
hostname: CDN_API.Hostname,
pathname: CDN_API.Pathname,
query: CDN_API.Query
};
requestDetails.query.search = packageItem.Details.Name;
let path = url.format(requestDetails);
logger.info(`Downloading '${path}'`);
let request = https.get(path, response => {
logger.info(`Response '${response.statusCode}' (${response.statusMessage}).`);
let allData = "";
response.on("data", (data) => {
allData += data;
});
response.on('end', () => __awaiter(this, void 0, void 0, function* () {
let parsedJson;
try {
parsedJson = JSON.parse(allData);
}
catch (err) {
logger.error(`Sorry, something wrong with response data from ${CDN_API.Hostname}. Please report a bug.`);
}
;
if (parsedJson !== undefined) {
logger.info(`Downloaded and parsed '${parsedJson.total}' result${(parsedJson.total > 1) ? 's' : ''}.`);
if (parsedJson.total > 0) {
let link = yield this.getLinkFromResponseByVersion(packageItem, parsedJson, splited);
if (link !== undefined) {
logger.info(`Cdn link successfully resolved.`);
logger.info(`'${link}'`);
}
else {
logger.warn(`Cannot resolve cdn link with version ${packageItem.Details.Version}.`);
}
resolve(link);
}
else {
if (!splited) {
let splitedName = this.tryToSplitPackageName(packageItem.Details.Name);
if (splitedName !== undefined) {
logger.info(`Trying to use splited package name: '${splitedName}'`);
let splitedPackageItem = {
FullName: packageItem.FullName,
MapName: packageItem.MapName,
Details: {
OriginalName: packageItem.Details.Name,
Name: splitedName,
Version: packageItem.Details.Version
}
};
let link = this.getCdnLink(splitedPackageItem, true);
resolve(link);
}
else {
resolve(undefined);
}
}
else {
resolve(undefined);
}
}
}
else {
resolve(undefined);
}
}));
});
request.on('error', (err) => {
logger.error(err.message);
resolve(undefined);
});
});
});
}
tryToResolveSplitedPackage(packageItem, assetIndex, found, link = undefined) {
let logger = logger_1.LoggerInstance.withType(`JSPM [${packageItem.FullName}]`);
let asset = found.assets[assetIndex];
let searchingFiles = new Array();
let originalName = (packageItem.Details.OriginalName || packageItem.Details.Name).toLowerCase();
searchingFiles.push(`${originalName}.min.js`);
searchingFiles.push(`${originalName}.js`);
let foundFile = searchingFiles.find(searchingFile => asset.files.findIndex(file => searchingFile === file) !== -1);
if (foundFile !== undefined) {
logger.info(`File '${foundFile}' found in '${found.name}@${asset.version}'`);
return this.buildCdnLinkWithCustomFile(link || found.latest, foundFile);
}
return undefined;
}
tryToSplitPackageName(name) {
let splited = name.split("-");
if (splited.length === 2) {
return splited[0];
}
return undefined;
}
checkIfFileExist(files, link, fileName) {
let resultObj = {
Found: false,
Link: link
};
files.forEach(originalName => {
if (originalName === fileName) {
resultObj.Found = true;
return false;
}
else if (originalName.toLocaleLowerCase() === fileName) {
resultObj.Found = true;
let parsedFile = path.parse(link);
resultObj.Link = parsedFile.dir + "/" + originalName;
return false;
}
});
return resultObj;
}
getLinkFromResponseByVersion(packageItem, responseDto, splited) {
return __awaiter(this, void 0, void 0, function* () {
let logger = logger_1.LoggerInstance.withType(`JSPM [${packageItem.FullName}]`);
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
let found = responseDto.results.find(x => x.name === packageItem.Details.Name);
if (found !== undefined) {
if (found.version === packageItem.Details.Version) {
logger.info(`Version '${found.version}' found.`);
if (!splited) {
resolve(found.latest);
}
else {
let foundAsset = found.assets.findIndex(x => x.version === packageItem.Details.Version);
if (foundAsset !== -1) {
resolve(this.tryToResolveSplitedPackage(packageItem, foundAsset, found));
}
else {
resolve(undefined);
}
}
}
else {
logger.info(`Not targeting the latest version '${found.version}', trying to find version '${packageItem.Details.Version}'`);
let assetIndex = found.assets.findIndex(x => x.version === packageItem.Details.Version);
if (assetIndex !== -1) {
let asset = found.assets[assetIndex];
logger.info(`Version '${packageItem.Details.Version}' found.`);
let link = this.buildCdnLink(found.latest, found.version, packageItem.Details.Version);
if (link !== undefined) {
if (splited) {
resolve(this.tryToResolveSplitedPackage(packageItem, assetIndex, found, link));
}
else {
let checkFile = path.parse(link).base;
logger.info(`Checking file '${checkFile}'`);
let results = this.checkIfFileExist(asset.files, link, checkFile);
if (!results.Found && checkFile.indexOf("-") !== -1) {
logger.info(`Checking file '${checkFile}'`);
checkFile = checkFile.split("-").join("");
results = this.checkIfFileExist(asset.files, link, checkFile);
}
if (results.Found) {
logger.info(`File successfully found.`);
resolve(results.Link);
}
else {
logger.info(`File does not found in '${packageItem.Details.Version}' version.`);
resolve(undefined);
}
}
}
else {
logger.error([
"Failed to resolve cdn link. Please report this error.",
`--- ERROR DETAILS ---`,
`LatestLink: ${found.latest}`,
`LatestVersion: ${found.version}`,
`TargetVersion: ${packageItem.Details.Version}`,
`---------------------`
].join("\r\n "));
resolve(link);
}
}
else {
resolve(undefined);
}
}
}
else {
logger.info(`Package '${packageItem.Details.Name}' with original name was not found. Searching file in assets.`);
let resolved = false;
for (let i = 0; i < responseDto.results.length; i++) {
let item = responseDto.results[i];
let foundAsset = item.assets.findIndex(x => x.version === packageItem.Details.Version);
if (foundAsset !== -1) {
let resolvedItem = this.tryToResolveSplitedPackage(packageItem, foundAsset, item);
if (resolvedItem !== undefined) {
resolved = true;
resolve(resolvedItem);
break;
}
}
}
if (!resolved) {
resolve(undefined);
}
}
}));
});
}
buildCdnLinkWithCustomFile(latestLink, targetFile) {
let currentFileName = path.parse(latestLink).base;
return latestLink.replace(currentFileName, targetFile);
}
buildCdnLink(latestLink, latestVersion, targetVersion) {
let linkDetails = latestLink.split(latestVersion);
if (linkDetails.length === 2) {
let link = linkDetails[0] + targetVersion + linkDetails[1];
return link;
}
else {
return undefined;
}
}
getPackagesList(registry = "npm") {
let prefix = `${registry}:`;
let packagesList = new Array();
jspm.setPackagePath('.');
let packagesMap = jspm.Loader().getConfig().map;
for (let name in packagesMap) {
let fullName = packagesMap[name];
if (fullName.indexOf(prefix) === 0) {
let details = fullName.slice(prefix.length, fullName.length).split("@");
packagesList.push({
MapName: name,
FullName: fullName,
Details: {
Name: details[0],
Version: details[1]
}
});
}
}
return packagesList;
}
}
exports.JspmCdnPathsBuilder = JspmCdnPathsBuilder;