{"version":3,"file":"package-fns.mjs","names":[],"sources":["../src/package-fns.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n                       ⚡ Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website:                  https://stormsoftware.com\n Repository:               https://github.com/storm-software/stryke\n Documentation:            https://docs.stormsoftware.com/projects/stryke\n Contact:                  https://stormsoftware.com/contact\n\n SPDX-License-Identifier:  Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { findFileName, findFilePath } from \"@stryke/path/file-path-fns\";\nimport { joinPaths } from \"@stryke/path/join-paths\";\nimport { getPackageName } from \"@stryke/string-format/package\";\nimport { isString } from \"@stryke/type-checks/is-string\";\nimport type { PackageJson } from \"@stryke/types/package-json\";\nimport type { PackageManager } from \"@stryke/types/package-manager\";\nimport { existsSync } from \"node:fs\";\nimport type { Range } from \"semver\";\nimport { subset } from \"semver\";\nimport { exists } from \"./exists\";\nimport { getParentPath } from \"./get-parent-path\";\nimport { getWorkspaceRoot } from \"./get-workspace-root\";\nimport { readJsonFile } from \"./json\";\nimport type { ResolveOptions } from \"./resolve\";\nimport { resolvePackage } from \"./resolve\";\n\n/**\n * Get the package manager used in the project\n *\n * @param dir - The path to the project\n * @returns The package manager used in the project\n */\nexport function getPackageManager(dir = getWorkspaceRoot()): PackageManager {\n  const lockFile = getParentPath(\n    [\"package-lock.json\", \"yarn.lock\", \"pnpm-lock.yaml\", \"bun.lock\"],\n    dir,\n    {\n      includeNameInResults: true\n    }\n  );\n\n  if (!lockFile) {\n    // default use pnpm\n    return \"pnpm\";\n  }\n\n  switch (findFileName(lockFile)) {\n    case \"yarn.lock\": {\n      return \"yarn\";\n    }\n    case \"pnpm-lock.yaml\": {\n      return \"pnpm\";\n    }\n    case \"bun.lock\": {\n      return \"bun\";\n    }\n    default: {\n      return \"npm\";\n    }\n  }\n}\n\n// Much of the below code comes from https://github.com/antfu-collective/local-pkg with some modifications\n\nasync function searchPackageJson(dir: string) {\n  let packageJsonPath;\n\n  while (true) {\n    if (!dir) {\n      return;\n    }\n    const newDir = findFilePath(dir);\n\n    if (newDir === dir) {\n      return;\n    }\n\n    dir = newDir;\n    packageJsonPath = joinPaths(dir, \"package.json\");\n\n    if (await exists(packageJsonPath)) {\n      break;\n    }\n  }\n\n  return packageJsonPath;\n}\n\nasync function getPackageJsonPath(name: string, options: ResolveOptions = {}) {\n  const entry = await resolvePackage(name, options);\n  if (!entry) {\n    return;\n  }\n\n  return searchPackageJson(entry);\n}\n\n/**\n * Get package info\n *\n * @param name - The name of the package\n * @param options - The options to use when resolving the package\n * @returns The package info\n */\nexport async function getPackageInfo(\n  name: string,\n  options: ResolveOptions = {}\n) {\n  const packageJsonPath = await getPackageJsonPath(name, options);\n  if (!packageJsonPath) {\n    return;\n  }\n\n  const packageJson = await readJsonFile<PackageJson>(packageJsonPath);\n\n  return {\n    name,\n    version: packageJson.version,\n    rootPath: findFilePath(packageJsonPath),\n    packageJsonPath,\n    packageJson\n  };\n}\n\n/**\n * Get the package info from the package.json file\n *\n * @param cwd - The current working directory\n * @returns The package info\n */\nexport async function loadPackageJson(\n  cwd = getWorkspaceRoot()\n): Promise<PackageJson | null> {\n  const path = getParentPath(\"package.json\", cwd, {\n    skipCwd: false,\n    includeNameInResults: true\n  });\n  if (!path || !existsSync(path)) {\n    return null;\n  }\n\n  return readJsonFile<PackageJson>(path);\n}\n\nexport interface PackageExistsOptions {\n  /**\n   * The current working directory\n   */\n  cwd?: string;\n}\n\nexport interface PackageMatchesOptions extends PackageExistsOptions {\n  /**\n   * The version range of the package to check\n   */\n  version?: string | Range;\n}\n\n/**\n * Check if a package is listed in the package.json file\n *\n * @param name - The name of the package\n * @param cwd - The current working directory\n * @returns An indicator specifying if the package is listed\n */\nexport async function isPackageListed(\n  name: string,\n  cwd?: string\n): Promise<boolean>;\n\n/**\n * Check if a package is listed in the package.json file\n *\n * @param name - The name of the package\n * @param options - The options to use when checking if the package is listed\n * @returns An indicator specifying if the package is listed\n */\nexport async function isPackageListed(\n  name: string,\n  options?: PackageExistsOptions\n): Promise<boolean>;\n\n/**\n * Check if a package is listed in the package.json file\n *\n * @param name - The name of the package\n * @param cwdOrOptions - The current working directory or options to use when checking if the package is listed\n * @returns An indicator specifying if the package is listed\n */\nexport async function isPackageListed(\n  name: string,\n  cwdOrOptions?: string | PackageExistsOptions\n): Promise<boolean> {\n  const packageName = getPackageName(name);\n  const cwd = isString(cwdOrOptions) ? cwdOrOptions : cwdOrOptions?.cwd;\n\n  const packageJson = await loadPackageJson(cwd);\n  if (!packageJson) {\n    return false;\n  }\n\n  return Boolean(\n    (packageJson.dependencies &&\n      packageName in packageJson.dependencies &&\n      packageJson.dependencies[packageName]) ||\n    (packageJson.devDependencies &&\n      packageName in packageJson.devDependencies &&\n      packageJson.devDependencies[packageName])\n  );\n}\n\nexport interface GetPackageListingReturn {\n  version: string;\n  type: \"dependencies\" | \"devDependencies\";\n}\n\n/**\n * Return the package version and dependency type listed in the package.json file\n *\n * @param name - The name of the package\n * @param cwdOrOptions - The current working directory or options to use when checking if the package is listed\n * @returns The version and type of the package if listed, otherwise undefined\n */\nexport async function getPackageListing(\n  name: string,\n  cwdOrOptions?: string | PackageExistsOptions\n): Promise<GetPackageListingReturn | undefined> {\n  const packageName = getPackageName(name);\n  const cwd = isString(cwdOrOptions) ? cwdOrOptions : cwdOrOptions?.cwd;\n\n  const packageJson = await loadPackageJson(cwd);\n  if (!packageJson) {\n    return undefined;\n  }\n\n  const version =\n    packageJson.dependencies && packageName in packageJson.dependencies\n      ? packageJson.dependencies[packageName]\n      : packageJson.devDependencies &&\n          packageName in packageJson.devDependencies\n        ? packageJson.devDependencies[packageName]\n        : undefined;\n  const type =\n    (packageJson.dependencies && packageName in packageJson.dependencies\n      ? \"dependencies\"\n      : packageJson.devDependencies &&\n          packageName in packageJson.devDependencies\n        ? \"devDependencies\"\n        : undefined) || undefined;\n\n  return version && type\n    ? {\n        version,\n        type\n      }\n    : undefined;\n}\n\n/**\n * Check if a package version matches a specific version range\n *\n * @param name - The name of the package\n * @param version - The version to check against\n * @param cwd - The current working directory\n * @returns An indicator specifying if the package version matches the range\n */\nexport async function doesPackageMatch(\n  name: string,\n  version: string,\n  cwd?: string\n): Promise<boolean> {\n  const pkg = await getPackageListing(name, { cwd });\n  if (!pkg) {\n    return false;\n  }\n\n  return (\n    pkg.version.startsWith(\"catalog:\") ||\n    pkg.version.startsWith(\"workspace:\") ||\n    subset(pkg.version, version)\n  );\n}\n\n/**\n * Check if a package exists\n *\n * @param name - The name of the package\n * @param options - The options to use when resolving the package\n * @returns An indicator specifying if the package exists\n */\nexport function isPackageExists(name: string, options: ResolveOptions = {}) {\n  return Boolean(resolvePackage(name, options));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAwCA,SAAgB,kBAAkB,MAAM,kBAAkB,EAAkB;CAC1E,MAAM,WAAW,cACf;EAAC;EAAqB;EAAa;EAAkB;EAAW,EAChE,KACA,EACE,sBAAsB,MACvB,CACF;AAED,KAAI,CAAC,SAEH,QAAO;AAGT,SAAQ,aAAa,SAAS,EAA9B;EACE,KAAK,YACH,QAAO;EAET,KAAK,iBACH,QAAO;EAET,KAAK,WACH,QAAO;EAET,QACE,QAAO;;;AAOb,eAAe,kBAAkB,KAAa;CAC5C,IAAI;AAEJ,QAAO,MAAM;AACX,MAAI,CAAC,IACH;EAEF,MAAM,SAAS,aAAa,IAAI;AAEhC,MAAI,WAAW,IACb;AAGF,QAAM;AACN,oBAAkB,UAAU,KAAK,eAAe;AAEhD,MAAI,MAAM,OAAO,gBAAgB,CAC/B;;AAIJ,QAAO;;AAGT,eAAe,mBAAmB,MAAc,UAA0B,EAAE,EAAE;CAC5E,MAAM,QAAQ,MAAM,eAAe,MAAM,QAAQ;AACjD,KAAI,CAAC,MACH;AAGF,QAAO,kBAAkB,MAAM;;;;;;;;;AAUjC,eAAsB,eACpB,MACA,UAA0B,EAAE,EAC5B;CACA,MAAM,kBAAkB,MAAM,mBAAmB,MAAM,QAAQ;AAC/D,KAAI,CAAC,gBACH;CAGF,MAAM,cAAc,MAAM,aAA0B,gBAAgB;AAEpE,QAAO;EACL;EACA,SAAS,YAAY;EACrB,UAAU,aAAa,gBAAgB;EACvC;EACA;EACD;;;;;;;;AASH,eAAsB,gBACpB,MAAM,kBAAkB,EACK;CAC7B,MAAM,OAAO,cAAc,gBAAgB,KAAK;EAC9C,SAAS;EACT,sBAAsB;EACvB,CAAC;AACF,KAAI,CAAC,QAAQ,CAAC,WAAW,KAAK,CAC5B,QAAO;AAGT,QAAO,aAA0B,KAAK;;;;;;;;;AAgDxC,eAAsB,gBACpB,MACA,cACkB;CAClB,MAAM,cAAc,eAAe,KAAK;CAGxC,MAAM,cAAc,MAAM,gBAFd,SAAS,aAAa,GAAG,eAAe,cAAc,IAEpB;AAC9C,KAAI,CAAC,YACH,QAAO;AAGT,QAAO,QACJ,YAAY,gBACX,eAAe,YAAY,gBAC3B,YAAY,aAAa,gBAC1B,YAAY,mBACX,eAAe,YAAY,mBAC3B,YAAY,gBAAgB,aAC/B;;;;;;;;;AAeH,eAAsB,kBACpB,MACA,cAC8C;CAC9C,MAAM,cAAc,eAAe,KAAK;CAGxC,MAAM,cAAc,MAAM,gBAFd,SAAS,aAAa,GAAG,eAAe,cAAc,IAEpB;AAC9C,KAAI,CAAC,YACH;CAGF,MAAM,UACJ,YAAY,gBAAgB,eAAe,YAAY,eACnD,YAAY,aAAa,eACzB,YAAY,mBACV,eAAe,YAAY,kBAC3B,YAAY,gBAAgB,eAC5B;CACR,MAAM,QACH,YAAY,gBAAgB,eAAe,YAAY,eACpD,iBACA,YAAY,mBACV,eAAe,YAAY,kBAC3B,oBACA,WAAc;AAEtB,QAAO,WAAW,OACd;EACE;EACA;EACD,GACD;;;;;;;;;;AAWN,eAAsB,iBACpB,MACA,SACA,KACkB;CAClB,MAAM,MAAM,MAAM,kBAAkB,MAAM,EAAE,KAAK,CAAC;AAClD,KAAI,CAAC,IACH,QAAO;AAGT,QACE,IAAI,QAAQ,WAAW,WAAW,IAClC,IAAI,QAAQ,WAAW,aAAa,IACpC,OAAO,IAAI,SAAS,QAAQ;;;;;;;;;AAWhC,SAAgB,gBAAgB,MAAc,UAA0B,EAAE,EAAE;AAC1E,QAAO,QAAQ,eAAe,MAAM,QAAQ,CAAC"}