UNPKG

simplr-gulp

Version:

Fully functional gulpfile.js implementation. Tailored for Single Page Application. Written in TypeScript.

342 lines (341 loc) 17.1 kB
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;