Uname: Linux webm016.cluster127.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64
Software: Apache
PHP version: 7.4.33 [ PHP INFO ] PHP os: Linux
Server Ip: 54.36.31.145
Your Ip: 216.73.216.182
User: homesquasz (91404) | Group: users (100)
Safe Mode: OFF
Disable Function:
_dyuweyrj4,_dyuweyrj4r,dl

name : ParseLockfile.js
/* eslint-disable security/detect-object-injection */
'use strict'

const fs = require('fs')
const path = require('path')
const yarnLockfileParser = require('@yarnpkg/lockfile')
const hash = require('object-hash')
const {ParsingError, ERROR_MESSAGES} = require('./common/ParsingError')
const {
  NO_OPTIONS,
  NO_PARSER_FOR_PATH,
  NO_PARSER_FOR_TYPE,
  READ_FAILED,
  PARSE_NPMLOCKFILE_FAILED,
  PARSE_YARNLOCKFILE_FAILED
} = ERROR_MESSAGES

class ParseLockfile {
  /**
   * constructor
   * @param {string} options.lockfilePath - path to the lockfile
   * @param {string} options.lockfileType - the package manager type
   * for lockfile
   */
  constructor (options) {
    if (!options || typeof options !== 'object') {
      throw new ParsingError(NO_OPTIONS)
    }

    this.options = {}
    this.options.lockfilePath = options.lockfilePath
    this.options.lockfileType = options.lockfileType
  }

  /**
   * Checks if lockfile type option was provided
   * @return boolean
   */
  isLockfileTypeGiven () {
    return typeof this.options.lockfileType === 'string' && this.options.lockfileType
  }

  /**
   * Synchronously parses a lockfile
   * @return {object} parsed file
   */
  parseSync () {
    const lockfileParser = this.resolvePkgMgrForLockfile()
    if (!lockfileParser) {
      if (this.isLockfileTypeGiven()) {
        throw new ParsingError(NO_PARSER_FOR_TYPE, this.options.lockfileType)
      }
      throw new ParsingError(NO_PARSER_FOR_PATH, this.options.lockfilePath)
    }

    let file
    try {
      // eslint-disable-next-line security/detect-non-literal-fs-filename
      file = fs.readFileSync(this.options.lockfilePath, 'utf8')
    } catch (error) {
      throw new ParsingError(READ_FAILED, this.options.lockfilePath, error)
    }

    return lockfileParser.call(this, file)
  }

  resolvePkgMgrForLockfile () {
    const lockfileResolversByPackageManager = {
      npm: this.parseNpmLockfile,
      npmjs: this.parseNpmLockfile,
      yarn: this.parseYarnLockfile,
      yarnpkg: this.parseYarnLockfile
    }

    let resolver
    if (this.isLockfileTypeGiven()) {
      resolver = lockfileResolversByPackageManager[this.options.lockfileType]
    }

    if (!resolver) {
      resolver = this.resolvePkgMgrByFilename()
    }

    return resolver
  }

  resolvePkgMgrByFilename () {
    const lockfileResolverByFilename = {
      'package-lock.json': this.parseNpmLockfile,
      'yarn.lock': this.parseYarnLockfile
    }

    const pathInfo = path.parse(this.options.lockfilePath)
    const baseFilename = pathInfo.base

    return lockfileResolverByFilename[baseFilename]
  }

  parseYarnLockfile (lockfileBuffer) {
    let parsedFile
    try {
      parsedFile = yarnLockfileParser.parse(lockfileBuffer)
    } catch (error) {
      throw new ParsingError(PARSE_YARNLOCKFILE_FAILED, this.options.lockfilePath, error)
    }
    return parsedFile
  }

  parseNpmLockfile (lockfileBuffer) {
    let flattenedDepTree
    try {
      const packageJsonParsed = JSON.parse(lockfileBuffer)

      // transform original format of npm's package-json to match yarns
      // so we have a unified format to validate against
      const npmDepsTree = packageJsonParsed.dependencies
      flattenedDepTree = npmDepsTree ? this._flattenNpmDepsTree(npmDepsTree) : {}
    } catch (error) {
      throw new ParsingError(PARSE_NPMLOCKFILE_FAILED, this.options.lockfilePath, error)
    }

    return {
      type: 'success',
      object: flattenedDepTree
    }
  }

  _flattenNpmDepsTree (npmDepsTree, npmDepMap = {}) {
    for (const [depName, depMetadata] of Object.entries(npmDepsTree)) {
      const depMetadataShortend = {
        version: depMetadata.version,
        resolved: depMetadata.resolved ? depMetadata.resolved : depMetadata.version,
        integrity: depMetadata.integrity,
        requires: depMetadata.requires
      }
      const hashedDepValues = hash(depMetadataShortend)

      npmDepMap[`${depName}@${depMetadata.version}-${hashedDepValues}`] = depMetadataShortend

      const nestedDepsTree = depMetadata.dependencies

      if (nestedDepsTree && Object.keys(nestedDepsTree).length !== 0) {
        this._flattenNpmDepsTree(nestedDepsTree, npmDepMap)
      }
    }

    return npmDepMap
  }
}

module.exports = ParseLockfile
© 2026 GrazzMean