<commit_before>import axios from 'axios';
import Q from 'q';

// TODO
// Add state validation!
// Allow users to enter a full state name
// For example, "California" would be converted to "CA"
// Also validate city and slugs

export default function dispensary(): object {
  function sendRequest(endpoint: string, options: object = {}, cb: object): undefined {
    let url = `/dispensaries${(endpoint ? `/${endpoint}?` : '?')}`;
    if (options) {
      if (options.sort) url = `${url}sort=${options.sort}&`;
      if (options.page) url = `${url}page=${options.page}`;
    }
    axios.get(url)
    .then((response: object): object => cb(null, response.data.data))
    .catch((err: object): object => cb(err));
  }

  return {

    all(options: object = {}): undefined {
      const deferred = Q.defer();
      sendRequest(null, options, (err: string, data: object): undefined => {
        if (err) return deferred.reject(err);
        return deferred.resolve(data);
      });
      return deferred.promise;
    },

    dispensary(state: string, city: string, slug: string): undefined {
      const deferred = Q.defer();
      if (!state) deferred.reject(new Error('State is required.'));
      if (!city) deferred.reject(new Error('City is required.'));
      if (!slug) deferred.reject(new Error('Slug is required.'));
      sendRequest(`${state}/${city}/${slug}`, null, (err: string, data: object): undefined => {
        if (err) return deferred.reject(err);
        return deferred.resolve(data);
      });
      return deferred.promise;
    },

    strains(state: string, city: string, slug: string, options: object = {}): undefined {
      const deferred = Q.defer();
      if (!state) deferred.reject(new Error('State is required.'));
      if (!city) deferred.reject(new Error('City is required.'));
      if (!slug) deferred.reject(new Error('Slug is required.'));
      sendRequest(`${state}/${city}/${slug}/strains`,
        options,
        (err: string, data: object): undefined => {
          if (err) return deferred.reject(err);
          return deferred.resolve(data);
        }
      );
      return deferred.promise;
    },

    extracts(state: string, city: string, slug: string, options: object = {}): undefined {
      const deferred = Q.defer();
      if (!state) deferred.reject(new Error('State is required.'));
      if (!city) deferred.reject(new Error('City is required.'));
      if (!slug) deferred.reject(new Error('Slug is required.'));
      sendRequest(`${state}/${city}/${slug}/extracts`,
        options,
        (err: string, data: object): undefined => {
          if (err) return deferred.reject(err);
          return deferred.resolve(data);
        }
      );
      return deferred.promise;
    },

    edibles(state: string, city: string, slug: string, options: object = {}): undefined {
      const deferred = Q.defer();
      if (!state) deferred.reject(new Error('State is required.'));
      if (!city) deferred.reject(new Error('City is required.'));
      if (!slug) deferred.reject(new Error('Slug is required.'));
      sendRequest(`${state}/${city}/${slug}/edibles`,
        options,
        (err: string, data: object): undefined => {
          if (err) return deferred.reject(err);
          return deferred.resolve(data);
        }
      );
      return deferred.promise;
    },

    products(state: string, city: string, slug: string, options: object = {}): undefined {
      const deferred = Q.defer();
      if (!state) deferred.reject(new Error('State is required.'));
      if (!city) deferred.reject(new Error('City is required.'));
      if (!slug) deferred.reject(new Error('Slug is required.'));
      sendRequest(`${state}/${city}/${slug}/products`,
        options,
        (err: string, data: object): undefined => {
          if (err) return deferred.reject(err);
          return deferred.resolve(data);
        }
      );
      return deferred.promise;
    },

  };
}
<commit_msg>validate states and allow full state names<commit_after>import axios from 'axios';
import Q from 'q';

// TODO validate city and slugs

export default function dispensary(): object {
  function sendRequest(endpoint: string, options: object = {}, cb: object): undefined {
    let url = `/dispensaries${(endpoint ? `/${endpoint}?` : '?')}`;
    if (options) {
      if (options.sort) url = `${url}sort=${options.sort}&`;
      if (options.page) url = `${url}page=${options.page}`;
    }
    axios.get(url)
    .then((response: object): object => cb(null, response.data.data))
    .catch((err: object): object => cb(err));
  }

  function validateState(state: string): string {
    const stateNames = [
      'ARIZONA', 'ALABAMA', 'ALASKA', 'ARIZONA', 'ARKANSAS', 'CALIFORNIA', 'COLORADO',
      'CONNECTICUT', 'DELAWARE', 'FLORIDA', 'GEORGIA', 'HAWAII', 'IDAHO', 'ILLINOIS', 'INDIANA',
      'IOWA', 'KANSAS', 'KENTUCKY', 'KENTUCKY', 'LOUISIANA', 'MAINE', 'MARYLAND', 'MASSACHUSETTS',
      'MICHIGAN', 'MINNESOTA', 'MISSISSIPPI', 'MISSOURI', 'MONTANA', 'NEBRASKA', 'NEVADA',
      'NEW HAMPSHIRE', 'NEW JERSEY', 'NEW MEXICO', 'NEW YORK', 'NORTH CAROLINA', 'NORTH DAKOTA',
      'OHIO', 'OKLAHOMA', 'OREGON', 'PENNSYLVANIA', 'RHODE ISLAND', 'SOUTH CAROLINA',
      'SOUTH DAKOTA', 'TENNESSEE', 'TEXAS', 'UTAH', 'VERMONT', 'VIRGINIA', 'WASHINGTON',
      'WEST VIRGINIA', 'WISCONSIN', 'WYOMING',
    ];
    const stateAbbr = [
      'AZ', 'AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA', 'HI', 'ID', 'IL', 'IN',
      'IA', 'KS', 'KY', 'KY', 'LA', 'ME', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV',
      'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'OH', 'OK', 'OR', 'PA', 'RI', 'SC', 'SD', 'TN', 'TX',
      'UT', 'VT', 'VA', 'WA', 'WV', 'WI', 'WY',
    ];

    if (stateAbbr.indexOf(state.toUpperCase()) > -1) return state;
    const stateNameIdx = stateNames.indexOf(state.toUpperCase());
    if (stateNameIdx > -1) return stateAbbr[stateNameIdx];
    return false;
  }

  return {

    all(options: object = {}): undefined {
      const deferred = Q.defer();
      sendRequest(null, options, (err: string, data: object): undefined => {
        if (err) return deferred.reject(err);
        return deferred.resolve(data);
      });
      return deferred.promise;
    },

    dispensary(state: string, city: string, slug: string): undefined {
      const deferred = Q.defer();
      if (!state) deferred.reject(new Error('State is required'));
      const validState = validateState(state);
      if (!validState) deferred.reject(new Error('Invalid State'));
      if (!city) deferred.reject(new Error('City is required.'));
      if (!slug) deferred.reject(new Error('Slug is required.'));
      sendRequest(`${validState}/${city}/${slug}`, null, (err: string, data: object): undefined => {
        if (err) return deferred.reject(err);
        return deferred.resolve(data);
      });
      return deferred.promise;
    },

    strains(state: string, city: string, slug: string, options: object = {}): undefined {
      const deferred = Q.defer();
      if (!state) deferred.reject(new Error('State is required'));
      const validState = validateState(state);
      if (!validState) deferred.reject(new Error('Invalid State'));
      if (!city) deferred.reject(new Error('City is required.'));
      if (!slug) deferred.reject(new Error('Slug is required.'));
      sendRequest(`${validState}/${city}/${slug}/strains`,
        options,
        (err: string, data: object): undefined => {
          if (err) return deferred.reject(err);
          return deferred.resolve(data);
        }
      );
      return deferred.promise;
    },

    extracts(state: string, city: string, slug: string, options: object = {}): undefined {
      const deferred = Q.defer();
      if (!state) deferred.reject(new Error('State is required'));
      const validState = validateState(state);
      if (!validState) deferred.reject(new Error('Invalid State'));
      if (!city) deferred.reject(new Error('City is required.'));
      if (!slug) deferred.reject(new Error('Slug is required.'));
      sendRequest(`${validState}/${city}/${slug}/extracts`,
        options,
        (err: string, data: object): undefined => {
          if (err) return deferred.reject(err);
          return deferred.resolve(data);
        }
      );
      return deferred.promise;
    },

    edibles(state: string, city: string, slug: string, options: object = {}): undefined {
      const deferred = Q.defer();
      if (!state) deferred.reject(new Error('State is required'));
      const validState = validateState(state);
      if (!validState) deferred.reject(new Error('Invalid State'));
      if (!city) deferred.reject(new Error('City is required.'));
      if (!slug) deferred.reject(new Error('Slug is required.'));
      sendRequest(`${validState}/${city}/${slug}/edibles`,
        options,
        (err: string, data: object): undefined => {
          if (err) return deferred.reject(err);
          return deferred.resolve(data);
        }
      );
      return deferred.promise;
    },

    products(state: string, city: string, slug: string, options: object = {}): undefined {
      const deferred = Q.defer();
      if (!state) deferred.reject(new Error('State is required'));
      const validState = validateState(state);
      if (!validState) deferred.reject(new Error('Invalid State'));
      if (!city) deferred.reject(new Error('City is required.'));
      if (!slug) deferred.reject(new Error('Slug is required.'));
      sendRequest(`${validState}/${city}/${slug}/products`,
        options,
        (err: string, data: object): undefined => {
          if (err) return deferred.reject(err);
          return deferred.resolve(data);
        }
      );
      return deferred.promise;
    },

  };
}

{'fraction_non_alphanumeric': 0.17694122474099908, 'fraction_numerical': 0.00020514924607652066, 'mean_word_length': 3.0863369656328583, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, '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': '2710771', 'n_tokens_mistral': 3072, 'n_tokens_neox': 2940, 'n_words': 793}