diff --git a/README.md b/README.md
index 16d29df0..840a9c1f 100644
--- a/README.md
+++ b/README.md
@@ -8,87 +8,163 @@
[](https://sonarcloud.io/component_measures?id=hoonoh_aws-spot-price&metric=coverage&view=list)
[](https://greenkeeper.io/)
-CLI utility to list current global AWS EC2 Spot Instance prices.
+Lists current global AWS EC2 Spot Instance prices.
-## Example
+Supports CLI and module usage.
+
+## CLI
+
+### Example

-## Installation
+### Installation
-### npm
+#### npm
`npm -g i aws-spot-price`
-### yarn
+#### yarn
`yarn global add aws-spot-price`
-### run with npx
+#### run with npx
`npx aws-spot-price`
-## Usage
+### Usage
`aws-spot-run [options]`
If no options are applied, it will fetch all recent pricing data from default regions and show top 20 cheapest instances.
-### Credentials
+#### Credentials
This CLI utility uses AWS-SDK and requires AWS Access & Secret keys. If environment variables pair `AWS_ACCESS_KEY_ID` & `AWS_SECRET_ACCESS_KEY` or `~/.aws/credentials` is available it will use it. Otherwise, you will need to supply credentials through CLI options [`--accessKeyId`](#accessKeyId) and [`--secretAccessKey`](#secretAccessKey).
-### Options
+#### Options
-#### --ui
+##### --ui
Start with UI mode.
-#### --region | -r
+##### --region | -r
AWS region to fetch data from. Accepts multiple string values.
Defaults to all available AWS region which does not require opt-in.
-#### --family
+##### --family
EC2 instance families to filter. Will be translated to `--familyType` and `--size` values.
Accepts multiple string values.
Choose from: `general`, `compute`, `memory`, `storage`, `acceleratedComputing`
-#### --instanceType | -i
+##### --instanceType | -i
Type of EC2 instance to filter. Accepts multiple string values.
Enter valid EC2 instance type name. e.g. `-i t3.nano t3a.nano`
-#### --familyType | -f
+##### --familyType | -f
EC2 Family type (`c4`, `c5`, etc..). Accepts multiple string values.
-#### --size | -s
+##### --size | -s
EC2 size (`large`, `xlarge`, etc..). Accepts multiple string values.
-#### --priceMax | -p
+##### --priceMax | -p
Maximum price.
-#### --productDescription | -d
+##### --productDescription | -d
Instance product description to filter. Accepts multiple string values.
You can use `linux` or `windows` (all in lowercase) as wildcard.
-#### --limit | -l
+##### --limit | -l
Limits list of price information items to be returned.
-#### --json | -j
+##### --json | -j
Outputs in JSON format. This option will silence any progress output.
-#### --accessKeyId
+##### --accessKeyId
Specific AWS Access Key ID. Requires `--secretAccessKey` option to be used together.
-#### --secretAccessKey
+##### --secretAccessKey
Specific AWS Secret Access Key. Requires `--accessKeyId` option to be used together.
+
+## Module
+
+### Installation
+
+#### npm
+
+`npm i aws-spot-price`
+
+#### yarn
+
+`yarn add aws-spot-price`
+
+### Example
+
+#### Code (es6)
+
+```javascript
+import { getGlobalSpotPrices } from 'aws-spot-price';
+
+(async () => {
+ const results = await getGlobalSpotPrices({
+ regions: ['us-east-1', 'us-east-2', 'us-west-1', 'us-west-2'],
+ familyTypes: ['c3', 'c4', 'c5'],
+ sizes: ['large', 'medium', 'xlarge'],
+ limit: 5,
+ });
+ console.log(JSON.stringify(results, null, 2));
+})();
+```
+
+#### Results
+
+```json
+[
+ {
+ "AvailabilityZone": "us-east-2a",
+ "InstanceType": "c4.large",
+ "ProductDescription": "Linux/UNIX",
+ "SpotPrice": "0.018100",
+ "Timestamp": "2019-11-05T03:07:19.000Z"
+ },
+ {
+ "AvailabilityZone": "us-east-2c",
+ "InstanceType": "c4.large",
+ "ProductDescription": "Linux/UNIX",
+ "SpotPrice": "0.018100",
+ "Timestamp": "2019-11-05T03:07:19.000Z"
+ },
+ {
+ "AvailabilityZone": "us-east-2a",
+ "InstanceType": "c5.large",
+ "ProductDescription": "Linux/UNIX",
+ "SpotPrice": "0.019000",
+ "Timestamp": "2019-11-04T14:51:42.000Z"
+ },
+ {
+ "AvailabilityZone": "us-east-2c",
+ "InstanceType": "c5.large",
+ "ProductDescription": "Linux/UNIX",
+ "SpotPrice": "0.019000",
+ "Timestamp": "2019-11-04T14:51:42.000Z"
+ },
+ {
+ "AvailabilityZone": "us-east-2b",
+ "InstanceType": "c5.large",
+ "ProductDescription": "Linux/UNIX",
+ "SpotPrice": "0.019300",
+ "Timestamp": "2019-11-04T14:51:42.000Z"
+ }
+]
+```
diff --git a/package.json b/package.json
index f5b7a83e..330495da 100644
--- a/package.json
+++ b/package.json
@@ -33,7 +33,7 @@
"changelog": "conventional-changelog -i CHANGELOG.md -s -p angular",
"test": "patch-package && jest --runInBand --verbose",
"test:coverage": "yarn test --coverage",
- "test:ci": "yarn test:coverage --ci --reporters=jest-junit --coverageReporters lcov --coverageReporters cobertura",
+ "test:ci": "yarn test:coverage --reporters=default jest-junit --coverageReporters lcov --coverageReporters cobertura --no-cache",
"lint": "eslint **/*.ts",
"types": "tsc",
"semantic-release": "semantic-release"
diff --git a/src/cli.spec.ts b/src/cli.spec.ts
index 46699123..5396458f 100644
--- a/src/cli.spec.ts
+++ b/src/cli.spec.ts
@@ -1,4 +1,5 @@
import { spawnSync } from 'child_process';
+import { readFileSync } from 'fs';
import mockConsole, { RestoreConsole } from 'jest-mock-console';
import { resolve } from 'path';
@@ -162,8 +163,17 @@ describe('cli', () => {
describe('test by spawnSync', () => {
const cliJsPath = resolve(__dirname, '../dist/cli.js');
it('should stdout help screen', () => {
- const s = spawnSync('node', [cliJsPath, '--help'], { encoding: 'utf-8' });
- expect(s.stdout).toMatchSnapshot();
+ let caughtError = false;
+ try {
+ console.log(cliJsPath);
+ console.log(readFileSync(cliJsPath).toString('utf8'));
+ const s = spawnSync('node', [cliJsPath, '--help'], { encoding: 'utf-8' });
+ expect(s.stdout).toMatchSnapshot();
+ } catch (error) {
+ caughtError = true;
+ console.error(error);
+ }
+ expect(caughtError).toBeFalsy();
});
});
});