UNPKG

typle

Version:

📦 Scan and install missing Typescript type definitions for your dependencies.

336 lines (298 loc) • 16.8 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var __defProp = Object.defineProperty; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty, __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues = exports.__spreadValues = (a, b) => { for (var prop in b || (b = {})) __hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) __propIsEnum.call(b, prop) && __defNormalProp(a, prop, b[prop]); return a; }; var __async = (__this, __arguments, generator) => new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }, rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }, step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); // src/utils/util.ts var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _semver = require('semver'); var _semver2 = _interopRequireDefault(_semver); var _crossspawn = require('cross-spawn'); var _crossspawn2 = _interopRequireDefault(_crossspawn); // ../../node_modules/.pnpm/is-unicode-supported@2.1.0/node_modules/is-unicode-supported/index.js var _process = require('process'); var _process2 = _interopRequireDefault(_process); function isUnicodeSupported() { let { env } = _process2.default, { TERM, TERM_PROGRAM } = env; return _process2.default.platform !== "win32" ? TERM !== "linux" : !!env.WT_SESSION || !!env.TERMINUS_SUBLIME || env.ConEmuTask === "{cmd::Cmder}" || TERM_PROGRAM === "Terminus-Sublime" || TERM_PROGRAM === "vscode" || TERM === "xterm-256color" || TERM === "alacritty" || TERM === "rxvt-unicode" || TERM === "rxvt-unicode-256color" || env.TERMINAL_EMULATOR === "JetBrains-JediTerm"; } // src/utils/util.ts var _nanospinner = require('nanospinner'); var _typleutil = require('typle-util'); var joincwd = _path2.default.join.bind(void 0, process.cwd()), spinner = _nanospinner.createSpinner.call(void 0, ), allowedPackageManagers = ["npm", "yarn", "pnpm", "bun"], defaultOptions = { silent: !0, install: !0, dryRun: !1, pkgManager: void 0, patterns: [], ignorePackages: [], ignoreDeps: [], additionalArgs: [] }; function clearSpinner() { spinner.stop(), process.stdout.moveCursor(0, -1), process.stdout.write(" ".repeat(process.stdout.columns || 50) + "\r"); } function niceTryPromise(fn) { return __async(this, null, function* () { try { return yield fn(); } catch (e) { } }); } function getPkgJson() { return __async(this, null, function* () { return yield _typleutil.readPkg.call(void 0, _path2.default.join(__dirname, "../package.json")); }); } function getVersion() { return __async(this, null, function* () { return (yield getPkgJson()).version; }); } function cleanSemver(version) { return _semver2.default.clean(version, { loose: !0 }) || _semver2.default.valid(_semver2.default.coerce(version)); } function getTypescriptVersion() { return __async(this, null, function* () { let pkgJson = (yield niceTryPromise(_typleutil.readPkg)) || {}, localTypescriptVersion = _typleutil.getDependencies.call(void 0, pkgJson).typescript; return localTypescriptVersion ? cleanSemver(localTypescriptVersion) : new Promise((resolve, reject) => { var _a; let proc = _crossspawn2.default.call(void 0, "tsc -v"); (_a = proc.stdout) == null || _a.on("data", (version) => { resolve(cleanSemver(version.toString())), proc.kill(); }), proc.once("error", reject), proc.once("exit", reject); }); }); } function matchVersion(dep, packument) { return Object.keys(packument.versions).filter((version) => { try { return (_semver2.default.satisfies(version, _semver2.default.validRange(dep.version) || "^" + _semver2.default.major(cleanSemver(dep.version) || dep.version), { includePrerelease: !0 }) || _semver2.default.satisfies(version, "^" + _semver2.default.major(cleanSemver(dep.version) || dep.version), { includePrerelease: !0 })) && !("deprecated" in packument.versions[version]); } catch (e) { return !1; } }).sort((a, b) => _semver2.default.rcompare(a, b))[0]; } function getUnicode(str, alt = "") { return isUnicodeSupported() ? str : alt; } // src/utils/logger.ts var _picocolors = require('picocolors'); var _picocolors2 = _interopRequireDefault(_picocolors); var logger = {}, levels = { info: _picocolors2.default.cyan("info"), warn: _picocolors2.default.yellow("warn"), error: _picocolors2.default.red("error"), success: _picocolors2.default.bold(_picocolors2.default.green(getUnicode("\u2714", "\u221A"))) }; function log(...msg) { console.log(...msg); } logger.info = (...msg) => { log(levels.info, ...msg); }; logger.success = (...msg) => { log(levels.success, ...msg); }; logger.warn = (...msg) => { log(levels.warn, ...msg); }; logger.error = (...msg) => { log(levels.error, ...msg); }; var logger_default = logger; // src/cli/runner.ts var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs); var _tinyglobby = require('tinyglobby'); // src/scanner.ts var _detectindent = require('detect-indent'); var _detectindent2 = _interopRequireDefault(_detectindent); var _installpkg = require('@antfu/install-pkg'); var _typlecore = require('typle-core'); // src/utils/session.ts var session = { install_count: 0 }; // src/utils/generate-list.ts function generateList(pkgs, filepath) { let list = `${" ".repeat(process.stdout.columns || 30)} ${getUnicode("\u{1F4E6} ")}typle ${_picocolors2.default.gray(_picocolors2.default.italic("- " + filepath))} ${_picocolors2.default.italic(`(added ${pkgs.length} package${pkgs.length > 1 ? "s" : ""})`)}`; return pkgs.forEach((pkg, i) => { let c = getUnicode(i === pkgs.length - 1 ? "\u2514\u2574" : "\u251C\u2574", "- "); list += ` ` + _picocolors2.default.white(c) + _picocolors2.default.gray(_typleutil.TYPES_PREFIX) + _picocolors2.default.blue(_picocolors2.default.bold(pkg.replace(_typleutil.TYPES_PREFIX, ""))); }), list + ` `; } // src/scanner.ts var { exit } = process, pkgCwd = joincwd("package.json"); function scan() { return __async(this, arguments, function* (pkgPath = pkgCwd, tsTag = "latest", options) { let cwd = _path2.default.resolve(pkgPath), pkgDir = _path2.default.relative(process.cwd(), cwd), prettyPkgPath = cwd === pkgCwd ? "" : _picocolors2.default.gray(_picocolors2.default.italic(" (" + pkgDir + ")")); spinner.start({ text: `scanning ${cwd === pkgCwd ? _picocolors2.default.blue("package.json") : _picocolors2.default.blue(pkgDir)} for typings\r`, color: "blue" }); let pkgJson = yield _typleutil.readPkg.call(void 0, pkgPath), types = [], libraries = []; try { types.push(...yield _typlecore.filterTypes.call(void 0, pkgJson, cwd)); } catch (error) { logger_default.error(error.message), exit(1); } if (yield Promise.all( types.map((lib) => __async(this, null, function* () { if (options.ignorePackages.includes(lib.name) || options.ignoreDeps.some((deps) => { deps === "deps" && (deps = "dependencies"); let pkgEl = pkgJson[deps] || pkgJson[deps + "Dependencies"]; return pkgEl == null ? void 0 : pkgEl[lib.name]; })) return; let dtlib = _typleutil.convertToTypes.call(void 0, lib.name), packument = yield _typlecore.fetchPackage.call(void 0, dtlib); if (!packument) { logger_default.warn(_picocolors2.default.bold(lib.name), "doesn't provide any type definitions"); return; } let tags = packument["dist-tags"], version = matchVersion(lib, packument) || tsTag && tags[tsTag] || tags.latest; if (!version || !packument.versions[version]) { logger_default.error(`No valid release tag found for ${packument.name}`); return; } let pkg = packument.versions[version]; libraries.push(pkg); })) ), clearSpinner(), !libraries.length) { logger_default.info("no typings to add" + prettyPkgPath); return; } if (console.log( generateList(libraries.map(({ name }) => name).sort(), cwd === pkgCwd ? "package.json" : pkgDir) ), options.dryRun) return; let pkgManager = options.pkgManager || ((yield _installpkg.detectPackageManager.call(void 0, cwd)) || "npm").split("@")[0], installCmd = pkgManager === "yarn" ? "add" : "install"; if (options.install) { let pkgs = libraries.map((pkg) => pkg.name.trim() + "@^" + pkg.version.trim()), additionalArgs = options.additionalArgs; Object.keys(options).filter((option) => !Object.keys(defaultOptions).includes(option)).forEach((option) => { let opt = options[option]; Array.isArray(opt) || (additionalArgs.push("--" + option), /^(true|false)$/i.test(opt) || additionalArgs.push(opt)); }); let cmd = `${pkgManager} ${installCmd} --save-dev ${pkgs.join(" ")} ${additionalArgs.join(" ")}`; logger_default.info(`$ ${cmd}`), options.silent && spinner.start({ text: `installing ${_picocolors2.default.cyan(pkgs.length + " package" + (pkgs.length > 1 ? "s" : ""))} via ${pkgManager}\r`, color: "cyan" }); try { yield _installpkg.installPackage.call(void 0, pkgs, { dev: !0, silent: options.silent, additionalArgs, cwd: _path2.default.dirname(cwd), packageManager: pkgManager }); } catch (e) { logger_default.error("Something went wrong while installing dependencies. Try running the following command yourself:", _picocolors2.default.gray(cmd)), exit(1); } options.silent && clearSpinner(); } else { pkgJson.devDependencies = pkgJson.devDependencies || {}, libraries.forEach((lib) => { pkgJson.devDependencies[lib.name] = `^${lib.version}`; }), pkgJson.devDependencies = Object.fromEntries(Object.keys(pkgJson.devDependencies).sort().map((key) => [key, pkgJson.devDependencies[key]])); let indent = _detectindent2.default.call(void 0, yield _fs2.default.promises.readFile(pkgPath, "utf8")).amount || 2; yield _fs2.default.promises.writeFile(pkgPath, JSON.stringify(pkgJson, void 0, indent), "utf8"), logger_default.info("successfully updated package.json"), logger_default.info(`run ${_picocolors2.default.cyan(`${pkgManager} ${installCmd}`)} to install newly added packages`); } session.install_count += libraries.length; }); } // src/updater.ts var _tinyupdatenotifier = require('tiny-update-notifier'); var _tinyupdatenotifier2 = _interopRequireDefault(_tinyupdatenotifier); function updater() { return __async(this, null, function* () { let pkg = yield getPkgJson(); try { let update = yield _tinyupdatenotifier2.default.call(void 0, { pkg }); update && logger_default.info(`update available: ${_picocolors2.default.gray(update.current)} ${getUnicode("\u2192", "->")} ${_picocolors2.default.green(update.latest)} (${update.type})`); } catch (e) { logger_default.warn("couldn't fetch new updates"); } }); } // src/cli/runner.ts var { exit: exit2 } = process; function run() { return __async(this, arguments, function* (options_ = {}) { var _a; let options = __spreadValues(__spreadValues({}, defaultOptions), options_), start = Date.now(), typescriptVersion = yield niceTryPromise(getTypescriptVersion), tsTag = typescriptVersion ? "ts" + _semver2.default.major(typescriptVersion) + "." + _semver2.default.minor(typescriptVersion) : void 0; typescriptVersion ? logger_default.info("typescript: v" + typescriptVersion) : logger_default.warn("couldn't find any typescript version, is it installed?"), options.pkgManager && !allowedPackageManagers.includes(options.pkgManager) && (logger_default.warn( _picocolors2.default.bold(options.pkgManager), "is not a valid or supported package manager", _picocolors2.default.gray(_picocolors2.default.italic(`(supported: ${_picocolors2.default.bold("npm")}, ${_picocolors2.default.bold("yarn")}, ${_picocolors2.default.bold("pnpm")} and ${_picocolors2.default.bold("bun")})`)) ), delete options.pkgManager), yield updater(); let pkgPath = joincwd("package.json"); if (!((_a = options.patterns) != null && _a.length)) _fs2.default.existsSync(pkgPath) || (logger_default.error("couldn't find 'package.json' in this directory"), exit2(1)), yield scan(pkgPath, tsTag, options); else { let files = yield _tinyglobby.glob.call(void 0, options.patterns, { dot: !0, absolute: !0 }); if (!files.length) { logger_default.info("no matching patterns found"); return; } logger_default.info(`found ${files.length} matching patterns`); for (let file of files) { let pkgPath2 = _path2.default.join(file, "package.json"); if (!_fs2.default.existsSync(pkgPath2)) { logger_default.warn("couldn't find 'package.json' in ", _path2.default.dirname(pkgPath2)); return; } yield scan(pkgPath2, tsTag, options); } } options.dryRun && logger_default.info(`no changes made ${_picocolors2.default.gray(_picocolors2.default.italic("(--dry-run)"))}`); let time = ((Date.now() - start) / 1e3).toFixed(1) + "s"; session.install_count ? logger_default.success(`added ${session.install_count} new typings in ${time}`) : logger_default.success(`no typings added in ${time}`); }); } // src/cli/installer.ts function install(_0) { return __async(this, arguments, function* (libs, options = {}) { _fs2.default.existsSync(joincwd("package.json")) || (logger_default.error("could't find 'package.json' in this directory"), process.exit(1)); let args = options, additionalArgs = []; Object.keys(args).forEach((arg) => { let opt = args[arg]; Array.isArray(opt) || (additionalArgs.push("--" + arg), /^(true|false)$/i.test(opt) || additionalArgs.push(opt)); }); let typescriptVersion = yield niceTryPromise(getTypescriptVersion), tsTag = typescriptVersion && "ts" + _semver2.default.major(typescriptVersion) + "." + _semver2.default.minor(typescriptVersion); typescriptVersion ? logger_default.info("typescript: v" + typescriptVersion) : logger_default.warn("couldn't find any typescript version, is it installed?"), options.pkgManager && !allowedPackageManagers.includes(options.pkgManager) && (logger_default.warn( options.pkgManager, "is not a valid or supported package manager", _picocolors2.default.gray(_picocolors2.default.italic(`(we only support ${_picocolors2.default.underline("npm")} ${_picocolors2.default.underline("yarn")} ${_picocolors2.default.underline("pnpm")} and ${_picocolors2.default.underline("bun")})`)) ), delete options.pkgManager), logger_default.warn("this feature is experimental"), yield updater(), logger_default.info("installing libraries"), yield _installpkg.installPackage.call(void 0, libs, { additionalArgs }); let libraries = []; yield Promise.all( libs.map((lib) => __async(this, null, function* () { let lastindex = lib.lastIndexOf("@"); lastindex !== -1 && (lib = lib.slice(0, Math.max(0, lastindex))); try { if (yield _typlecore.hasOwnTypes.call(void 0, lib)) return; } catch (error) { logger_default.error(error.message), process.exit(1); } let dtlib = _typleutil.convertToTypes.call(void 0, lib), packument = yield _typlecore.fetchPackage.call(void 0, dtlib); if (!packument) { logger_default.warn(lib, "doesn't provide any type definitions"); return; } let tags = packument["dist-tags"], tag = tsTag && tags[tsTag] || tags.latest; if (!tag || !packument.versions[tag]) { logger_default.error(`No valid release tag found for ${packument.name}`); return; } let pkg = packument.versions[tag]; libraries.push(pkg); })) ), libraries.length && (logger_default.info("installing types"), yield _installpkg.installPackage.call(void 0, libraries.map((lib) => lib.name + "@^" + lib.version), { dev: !0, additionalArgs })); }); } exports.__spreadValues = __spreadValues; exports.__async = __async; exports.joincwd = joincwd; exports.getVersion = getVersion; exports.logger_default = logger_default; exports.run = run; exports.install = install;