# CardX Common Library

## Installation

``` shell
npm --save install @cardx/common
```

## Constants

``` javascript
import { ACCOUNT, ENV } from "@cardx/common"
```

### Account Attributes

#### `ACCOUNT.{name}.{attribute}`

Account Names:

* NONPRODUCTION
* PRODUCTION
* SANDBOX

Account Attributes:

* CODE
* ID

Example:

``` javascript
console.log([ACCOUNT.SANDBOX.CODE, ACCOUNT.SANDBOX.ID]);
//> [sbx, 492297341765]
```

### Currency Codes

#### `CURRENCY`

* `CAD`
* `USD`

### Environment Codes

#### `ENV.{name}`

Environment Names:

* BETA
* DEMO
* EDGE
* KITCHEN
* LOCAL
* PRODUCTION
* SANDBOX
* TEST

Example:

``` javascript
console.log(ENV.EDGE);
//> edg
```

### `GATEWAY`

[Gateway constants](GATEWAY.md)

### `HTTP`

[HTTP constants](HTTP.md)

### Test Cards

#### `TESTCARDS`

Refers to an array of test cards that will authorize with Test Plug n' Pay accounts, and give appropriate responses from the Pricing Technology

Example:

``` javascript
console.log(TESTCARDS[0]);
//> {
//>   'brand': 'Visa',
//>   'type': 'Debit',
//>   'regulated': 'true',
//>   'number': '4117760000000001'
//> }
```

## Functions

### `cardxProjectUuid(attributes:mixed, settings:object)`

Takes `attributes` that form uniqueness within a CardX project and returns a v5 UUID.
`settings` help ensure uniqueness between projects and environments
(i.e., so generating a UUID from the same input in different environments or projects generates different values).

#### Settings

| Key       | Required | Default                   | Description                                             |
| --------- | -------- | ------------------------- | ------------------------------------------------------- |
| `env`     | Yes      | process.env.AWS_ENV       | CardX AWS environment (should be set in build pipeline) |
| `project` | Yes      | process.env.CARDX_PROJECT | CardX project                                           |
| `model`   | No       | `undefined`               | Table or model within project                           |

### `decodeHumanReference(reference:string)`

Converts a reference derived from `humanUuidReference` to a partial UUID suitable for searching.
E.g., `4707-6705-63431604` becomes `9c7dc5ce-3384`.

### `deleteKeyFromHeaders(key:string, headers:object)`

Case-insensitive delete of key from headers object (per HTTP spec)

### `getHeaderKeys(headers:object, keyMap:object)`

Normalizes headers (to lowercase) and returns an object with keys
that are keys from the keyMap and values that are the corresponding key's
value from the headers.

E.g., headers={One:1, Two:2}, keyMap={uno:ONE, dos:TWO}

returns {uno:1, dos:2}

### `formatAsJsonString(subject:any)`

Returns pretty-formatted string if parsable as JSON, cast to string otherwise

### `getBrandForNumber(cardNumber:string)`

Pass a PAN or masked card number and receive the brand name back

### `getCardXOrigin(headers:object)`

Returns the origin, if it's a CardX origin, or false

### `humanUuidReference(uuid:string, settings:object)`

Convert a UUID to a human-readable reference to lookup the original UUID.
E.g., `9c7dc5ce-3384-4427-a62c-703c1eded0ff` becomes `4707-6705-63431604`

The settings object is optional and provides reasonable defaults:

* `nibbles` (`4`) defines the number of 4-character "nibbles" in the resulting reference
* `dashes` (`2`) defines the number of dash characters (`-`) to include in the reference

### `keyFromHeaders(key:string, headers:object)`

Case-insensitive key lookup in headers object (per HTTP spec)

### `mapCardBrand({ cardName:string })`

Takes an input string and attempt to return a normalized version of the card brand name.

### `nest(subject:object)`

Takes a flat object with keys reflecting a hierarchy and returns a nested object reflecting that hierarchy

#### Example

Input subject:

``` json
{
  "one": "1",
  "two.one": "21",
  "three.one.one:": "311",
  "three.two.one:": "321",
  "three.one.two:": "312",
  "three.two.two:": "322",
  "three.three:": "33",
  "two.two": "22"
}
```

Returned result:

``` json
{
  "one": "1",
  "two": {
    "one": "21",
    "two": "22"
  },
  "three": {
    "one": {
      "one": "311",
      "two": "312"
    },
    "two": {
      "one": "321",
      "two": "322"
    },
    "three": "33"
  }
}
```

### `objectToOrderedArray(object:object)`

Takes an object and returns an array of key:value pairs (objects) ordered by key

### `objectToOrderedString(object:object)`

Takes an object and returns a string of key:value pairs ordered by key

### `parseMilliseconds(value:number)`

Turn values that "look like seconds" (e.g., 30, 120) into milliseconds.
Optional second parameter, `maxSeconds`, sets "tipping point" after which values are no longer converted (default: `499`)

### `roundCents(value:string|number)`

Rounds values to the nearest cent.
I.e., pads and fixes binary math precision.
Returns unexpected inputs (`undefined`, NaN strings, etc) unaltered

### `subdomainFromEnv(domain:string, { env:string })`

Takes a domain and returns the appropriate subdomain based on `process.env.AWS_ENV` or the `env` specified in the second parameter

### `formUrlencodedStringToObject(string)`

takes in a string like `x=y&a=b` and turns it into a js object like `{ x: "y", a: "b" }`

## Default Object

Attributes can also be accessed through the default object:

* `CONSTANTS` (defined above)
* `functions` (defined above)

Example:

``` javascript
import CommonLib from "cardx-lib-common";

console.log(CommonLib.CONSTANTS.ACCOUNT.SANDBOX.CODE)
//> sbx
```

## Changelog

* 2.0.0: Breaking changes inside PORTAL.MERCHANTS
* 2.1.0: Adds two international debit cards
* 2.2.0: Adds HTTP constants
* 2.3.0: (skipped)
* 2.4.0: (skipped)
* 2.5.0: Adds CURRENCY constants
* 2.6.0: Adds GATEWAY constants
* 2.7.0: Adds cardxProjectUuid function
* 2.8.0: Adds keyFromHeaders function
* 2.8.1: Adds PORTAL.HEADER, PORTAL.SYSTEM.ROLES, PORTAL.SYSTEM.PERMISSIONS
* 2.9.0: Adds formatAsJsonString function
* 2.10.0: Adds subdomainFromEnv function
* 2.10.5: Fixes Firefox/IE incompatibility introduced in 2.7.0
* 2.11.0: Adds humanUuidReference (includes bug), decodeHumanReference
* 2.12.0: Adds deleteKeyFromHeaders, parseMilliseconds
* 2.12.1: Patches initial zero-padding bug in humanUuidReference ("00A" was "12" not "0012")
* 2.13.0: Adds AVS + CVV constants and map between PnP response values and CardX responses
* 2.14.0: Adds sleep function; GATEWAY.STATUS
* 2.15.0 Adds roundCents function
* 2.15.1 Expands GATEWAY
* 2.15.2 Adds isValidEmail function
* 2.15.3 Adds BILLING_PLANS status constants to PORTAL.
* 2.15.4 Adds calculateEndDate function for calculating billing plan dates
* 2.16.0 Adds nest function
* 2.17.0 Adds getCardXOrigin function
* 2.17.1 Moves @babel/runtime to devDependencies (far-fetched but non-zero risk of breaking)
* 2.17.2 Moves @babel/runtime back to dependencies because, yes, it does break things.  Of course it does
* 2.17.5 Adds `formUrlencodedStringToObject` function
* 2.18.0 Adds `getHeaderKeys` function
* 2.18.1 Adds `SHOULD_RECORD_TRANSACTION` constant to CardX custom headers

## License

© CardX. All rights reserved.
