<commit_before>/* @flow */

import type { PackageInfo } from "./types";
import type { RegistryNames } from "./registries";
import type PackageResolver from "./package-resolver";
import type Reporter from "./reporters/_base";
import type Lockfile from "./lockfile";
import type Config from "./config";
import mergeEngineDependencies from "./util/merge-engine-dependencies";
import PackageReference from "./package-reference";
import { registries as registryResolvers } from "./resolvers";
import { MessageError } from "./errors";
import * as constants from "./constants";
import * as versionUtil from "./util/version";
import * as resolvers from "./resolvers";

let invariant = require("invariant");

export default class PackageRequest {
  constructor({
    pattern,
    registry,
    config,
    reporter,
    lockfile,
    resolver,
    parentRequest
  }: {
    pattern: string,
    registry: RegistryNames,
    config: Config,
    reporter: Reporter,
    lockfile: Lockfile,
    resolver: PackageResolver,
    parentRequest: ?PackageRequest // eslint-disable-line no-unused-vars
  }) {
    this.parentRequest = parentRequest;
    this.lockfile      = lockfile;
    this.registry      = registry;
    this.reporter      = reporter;
    this.resolver      = resolver;
    this.pattern       = pattern;
    this.config        = config;
  }

  static getExoticResolver(pattern: string): ?Function { // TODO make this type more refined
    for (let name in resolvers.exotics) {
      let Resolver = resolvers.exotics[name];
      if (Resolver.isVersion(pattern)) return Resolver;
    }
  }

  parentRequest: ?PackageRequest;
  lockfile: Lockfile;
  reporter: Reporter;
  resolver: PackageResolver;
  pattern: string;
  config: Config;
  registry: RegistryNames;

  getHuman(): string {
    let chain = [];

    let delegator = this;
    do {
      chain.push(`${delegator.registry}:${delegator.pattern}`);
    } while (delegator = delegator.parentRequest);

    return chain.reverse().join(" -> ");
  }

  getLocked(remoteType: string): ?Object {
    let shrunk = this.lockfile.getLocked(this.pattern);

    if (shrunk) {
      let resolvedParts = versionUtil.explodeHashedUrl(shrunk.resolved);

      return {
        name: shrunk.name,
        version: shrunk.version,
        uid: shrunk.uid,
        remote: {
          resolved: shrunk.resolved,
          type: remoteType,
          reference: resolvedParts.url,
          hash: resolvedParts.hash,
          registry: shrunk.registry
        },
        dependencies: shrunk.dependencies
      };
    }
  }

  /**
   * TODO description
   */

  async findVersionOnRegistry(pattern: string): Promise<PackageInfo> {
    let range = "latest";
    let name  = pattern;

    // matches a version tuple in the form of NAME@VERSION. allows the first character to
    // be an @ for scoped packages
    let match = pattern.match(/^(.{1,})@(.*?)$/);
    if (match) {
      name = match[0];
      range = match[1] || "*";
    }

    let exoticResolver = PackageRequest.getExoticResolver(range);
    if (exoticResolver) {
      let data = await this.findExoticVersionInfo(exoticResolver, range);

      // clone data as we're manipulating it in place and this could be resolved multiple
      // times
      data = Object.assign({}, data);

      // this is so the returned package response uses the overriden name. ie. if the
      // package's actual name is `bar`, but it's been specified in package.json like:
      //   "foo": "http://foo.com/bar.tar.gz"
      // then we use the foo name
      data.name = name;

      return data;
    }

    let Resolver = registryResolvers[this.registry];
    if (!Resolver) {<commit_msg>fixed version tuple index lookup<commit_after>/* @flow */

import type { PackageInfo } from "./types";
import type { RegistryNames } from "./registries";
import type PackageResolver from "./package-resolver";
import type Reporter from "./reporters/_base";
import type Lockfile from "./lockfile";
import type Config from "./config";
import mergeEngineDependencies from "./util/merge-engine-dependencies";
import PackageReference from "./package-reference";
import { registries as registryResolvers } from "./resolvers";
import { MessageError } from "./errors";
import * as constants from "./constants";
import * as versionUtil from "./util/version";
import * as resolvers from "./resolvers";

let invariant = require("invariant");

export default class PackageRequest {
  constructor({
    pattern,
    registry,
    config,
    reporter,
    lockfile,
    resolver,
    parentRequest
  }: {
    pattern: string,
    registry: RegistryNames,
    config: Config,
    reporter: Reporter,
    lockfile: Lockfile,
    resolver: PackageResolver,
    parentRequest: ?PackageRequest // eslint-disable-line no-unused-vars
  }) {
    this.parentRequest = parentRequest;
    this.lockfile      = lockfile;
    this.registry      = registry;
    this.reporter      = reporter;
    this.resolver      = resolver;
    this.pattern       = pattern;
    this.config        = config;
  }

  static getExoticResolver(pattern: string): ?Function { // TODO make this type more refined
    for (let name in resolvers.exotics) {
      let Resolver = resolvers.exotics[name];
      if (Resolver.isVersion(pattern)) return Resolver;
    }
  }

  parentRequest: ?PackageRequest;
  lockfile: Lockfile;
  reporter: Reporter;
  resolver: PackageResolver;
  pattern: string;
  config: Config;
  registry: RegistryNames;

  getHuman(): string {
    let chain = [];

    let delegator = this;
    do {
      chain.push(`${delegator.registry}:${delegator.pattern}`);
    } while (delegator = delegator.parentRequest);

    return chain.reverse().join(" -> ");
  }

  getLocked(remoteType: string): ?Object {
    let shrunk = this.lockfile.getLocked(this.pattern);

    if (shrunk) {
      let resolvedParts = versionUtil.explodeHashedUrl(shrunk.resolved);

      return {
        name: shrunk.name,
        version: shrunk.version,
        uid: shrunk.uid,
        remote: {
          resolved: shrunk.resolved,
          type: remoteType,
          reference: resolvedParts.url,
          hash: resolvedParts.hash,
          registry: shrunk.registry
        },
        dependencies: shrunk.dependencies
      };
    }
  }

  /**
   * TODO description
   */

  async findVersionOnRegistry(pattern: string): Promise<PackageInfo> {
    let range = "latest";
    let name  = pattern;

    // matches a version tuple in the form of NAME@VERSION. allows the first character to
    // be an @ for scoped packages
    let match = pattern.match(/^(.{1,})@(.*?)$/);
    if (match) {
      name = match[1];
      range = match[2] || "*";
    }

    let exoticResolver = PackageRequest.getExoticResolver(range);
    if (exoticResolver) {
      let data = await this.findExoticVersionInfo(exoticResolver, range);

      // clone data as we're manipulating it in place and this could be resolved multiple
      // times
      data = Object.assign({}, data);

      // this is so the returned package response uses the overriden name. ie. if the
      // package's actual name is `bar`, but it's been specified in package.json like:
      //   "foo": "http://foo.com/bar.tar.gz"
      // then we use the foo name
      data.name = name;

      return data;
    }

    let Resolver = registryResolvers[this.registry];
    if (!Resolver) {
{'fraction_non_alphanumeric': 0.11595383570943653, 'fraction_numerical': 0.000814663951120163, 'mean_word_length': 2.779374037968189, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3357715', 'n_tokens_mistral': 2131, 'n_tokens_neox': 2064, 'n_words': 608}