UNPKG

@microsoft/kiota

Version:

npm package exposing Kiota CLI functionality to TypeScript

232 lines 9.61 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ensureKiotaIsPresent = ensureKiotaIsPresent; exports.ensureKiotaIsPresentInPath = ensureKiotaIsPresentInPath; exports.getKiotaPath = getKiotaPath; exports.getRuntimeDependenciesPackages = getRuntimeDependenciesPackages; exports.getCurrentPlatform = getCurrentPlatform; const adm_zip_1 = __importDefault(require("adm-zip")); const crypto_1 = require("crypto"); const https = __importStar(require("https")); const fs = __importStar(require("fs")); const path = __importStar(require("path")); const config_1 = require("./config"); const runtime_json_1 = __importDefault(require("./runtime.json")); const kiotaInstallStatusKey = "kiotaInstallStatus"; const installDelayInMs = 30000; // 30 seconds const state = {}; let kiotaPath; const binariesRootDirectory = '.kiotabin'; const baseDownloadUrl = "https://github.com/microsoft/kiota/releases/download"; const windowsPlatform = 'win'; const osxPlatform = 'osx'; const linuxPlatform = 'linux'; /** * Checks if a file or directory exists asynchronously * @param filePath Path to check * @returns Promise<boolean> true if exists, false otherwise */ async function checkFileExists(filePath) { try { await fs.promises.access(filePath); return true; } catch { return false; } } /** * Checks if a directory is empty asynchronously * @param dirPath Directory path to check * @returns Promise<boolean> true if directory is empty or doesn't exist, false otherwise */ async function isDirectoryEmpty(dirPath) { try { const files = await fs.promises.readdir(dirPath); return files.length === 0; } catch { // If directory doesn't exist, consider it as "empty" for our use case return true; } } async function runIfNotLocked(action) { const installStartTimeStamp = state[kiotaInstallStatusKey]; const currentTimeStamp = new Date().getTime(); if (!installStartTimeStamp || (currentTimeStamp - installStartTimeStamp) > installDelayInMs) { //locking the context to prevent multiple downloads across multiple instances //overriding after 30 seconds to prevent stale locks state[kiotaInstallStatusKey] = currentTimeStamp; try { await action(); } finally { state[kiotaInstallStatusKey] = undefined; } } } async function ensureKiotaIsPresent() { const installPath = getKiotaPathInternal(false); if (installPath) { const runtimeDependencies = getRuntimeDependenciesPackages(); const currentPlatform = getCurrentPlatform(); await ensureKiotaIsPresentInPath(installPath, runtimeDependencies, currentPlatform); } } async function ensureKiotaIsPresentInPath(installPath, runtimeDependencies, currentPlatform) { if (installPath) { if (!await checkFileExists(installPath) || await isDirectoryEmpty(installPath)) { await runIfNotLocked(async () => { try { const packageToInstall = runtimeDependencies.find((p) => p.platformId === currentPlatform); if (!packageToInstall) { throw new Error("Could not find package to install"); } fs.mkdirSync(installPath, { recursive: true }); const zipFilePath = `${installPath}.zip`; // If env variable that points to kiota binary zip exists, use it to copy the file instead of downloading it const kiotaBinaryZip = process.env.KIOTA_SIDELOADING_BINARY_ZIP_PATH; if (kiotaBinaryZip && await checkFileExists(kiotaBinaryZip)) { fs.copyFileSync(kiotaBinaryZip, zipFilePath); } else { const downloadUrl = getDownloadUrl(currentPlatform); await downloadFileFromUrl(downloadUrl, zipFilePath); if (!await doesFileHashMatch(zipFilePath, packageToInstall.sha256)) { throw new Error("Hash validation of the downloaded file mismatch"); } } unzipFile(zipFilePath, installPath); if ((currentPlatform.startsWith(linuxPlatform) || currentPlatform.startsWith(osxPlatform)) && installPath) { const fileName = getKiotaFileName(); const kiotaFilePath = path.join(installPath, fileName); makeExecutable(kiotaFilePath); } } catch (error) { fs.rmSync(installPath, { recursive: true, force: true }); throw new Error("Kiota download failed. Check the logs for more information."); } }); } } } function getKiotaPath() { if (!kiotaPath) { kiotaPath = getKiotaPathInternal(); if (!kiotaPath) { throw new Error("Could not find kiota"); } } return kiotaPath; } function makeExecutable(path) { fs.chmodSync(path, 0o755); } function getBaseDir() { return (0, config_1.getKiotaConfig)().binaryLocation || path.resolve(__dirname); } function getRuntimeVersion() { return (0, config_1.getKiotaConfig)().binaryVersion || runtime_json_1.default.kiotaVersion; } function getKiotaFileName() { return process.platform === 'win32' ? 'kiota.exe' : 'kiota'; } function getKiotaPathInternal(withFileName = true) { const fileName = getKiotaFileName(); const runtimeDependencies = getRuntimeDependenciesPackages(); const currentPlatform = getCurrentPlatform(); const packageToInstall = runtimeDependencies.find((p) => p.platformId === currentPlatform); const baseDir = getBaseDir(); const runtimeVersion = getRuntimeVersion(); if (packageToInstall) { const installPath = path.join(baseDir, binariesRootDirectory); const directoryPath = path.join(installPath, runtimeVersion, currentPlatform); if (withFileName) { return path.join(directoryPath, fileName); } return directoryPath; } return undefined; } function unzipFile(zipFilePath, destinationPath) { const zip = new adm_zip_1.default(zipFilePath); zip.extractAllTo(destinationPath, true); } async function doesFileHashMatch(destinationPath, hashValue) { const hash = (0, crypto_1.createHash)('sha256'); return new Promise((resolve, reject) => { fs.createReadStream(destinationPath).pipe(hash).on('finish', () => { const computedValue = hash.digest('hex'); hash.destroy(); resolve(computedValue.toUpperCase() === hashValue.toUpperCase()); }); }); } function downloadFileFromUrl(url, destinationPath) { return new Promise((resolve) => { https.get(url, (response) => { if (response.statusCode && response.statusCode >= 300 && response.statusCode < 400 && response.headers.location) { resolve(downloadFileFromUrl(response.headers.location, destinationPath)); } else { const filePath = fs.createWriteStream(destinationPath); response.pipe(filePath); filePath.on('finish', () => { filePath.close(); resolve(undefined); }); } }); }); } function getDownloadUrl(platform) { return `${baseDownloadUrl}/v${getRuntimeVersion()}/${platform}.zip`; } function getRuntimeDependenciesPackages() { if (runtime_json_1.default.runtimeDependencies) { return JSON.parse(JSON.stringify(runtime_json_1.default.runtimeDependencies)); } throw new Error("No runtime dependencies found"); } function getCurrentPlatform() { const binPathSegmentOS = process.platform === 'win32' ? windowsPlatform : process.platform === 'darwin' ? osxPlatform : linuxPlatform; return `${binPathSegmentOS}-${process.arch}`; } //# sourceMappingURL=install.js.map