diff --git a/.azure-pipelines-steps.yml b/.azure-pipelines-steps.yml
index 063cc72d..c08e5a42 100644
--- a/.azure-pipelines-steps.yml
+++ b/.azure-pipelines-steps.yml
@@ -28,7 +28,7 @@ steps:
condition: succeededOrFailed()
# Check types
- - script: yarn lint:types
+ - script: yarn types
displayName: "Check types"
condition: succeededOrFailed()
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml
index 0b08320f..8b89fa7e 100644
--- a/.azure-pipelines.yml
+++ b/.azure-pipelines.yml
@@ -5,6 +5,21 @@ trigger:
tags:
include:
- latest
+ paths:
+ exclude:
+ - .github/*
+ - bin/*
+ - docs/*
+ - "*.md"
+ - .codeclimate.yml
+ - .eslintrc.js
+ - .gitignore
+ - .npmignore
+ - .prettierignore
+ - aws-spot-price.code-workspace
+ - commitlint.config.js
+ - webpack.config.js
+ - yarn.lock
jobs:
- job: Release
diff --git a/.github/workflows/ec2-gen.yml b/.github/workflows/ec2-gen.yml
index dfc229a3..2e610e52 100644
--- a/.github/workflows/ec2-gen.yml
+++ b/.github/workflows/ec2-gen.yml
@@ -27,7 +27,7 @@ jobs:
run: yarn lint
- name: Check types
- run: yarn lint:types
+ run: yarn types
- name: Run tests and update snapshots
run: yarn test -u
diff --git a/.gitignore b/.gitignore
index 610217f6..f61153bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ coverage
dist
junit.xml
node_modules
+types
diff --git a/.npmignore b/.npmignore
index a78dc97f..7e1d3000 100644
--- a/.npmignore
+++ b/.npmignore
@@ -14,11 +14,11 @@ docs/
junit.xml
node_modules/
patches/
+scripts/
sonar-project.properties
src/
stats.json
test/
tsconfig*.json
-util/
webpack.config.js
yarn.lock
\ No newline at end of file
diff --git a/README.md b/README.md
index 16d29df0..4b595232 100644
--- a/README.md
+++ b/README.md
@@ -8,87 +8,163 @@
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=hoonoh_aws-spot-price&metric=coverage)](https://sonarcloud.io/component_measures?id=hoonoh_aws-spot-price&metric=coverage&view=list)
[![Greenkeeper badge](https://badges.greenkeeper.io/hoonoh/aws-spot-price.svg)](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
![Example](https://raw.githubusercontent.com/hoonoh/aws-spot-price/master/docs/preview.svg?sanitize=true)
-## 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
+
+```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/bin/aws-spot-price b/bin/aws-spot-price
index 20a0b1f0..d1c523a9 100755
--- a/bin/aws-spot-price
+++ b/bin/aws-spot-price
@@ -1,2 +1,2 @@
#!/usr/bin/env node
-require('../dist/aws-spot-price.bundle');
+require('../dist/cli');
diff --git a/package.json b/package.json
index 14743e37..268003d7 100644
--- a/package.json
+++ b/package.json
@@ -22,18 +22,20 @@
"name": "hoonoh"
},
"bin": "bin/aws-spot-price",
+ "main": "dist/module.js",
+ "types": "types/module.d.ts",
"license": "MIT",
"scripts": {
- "prepublishOnly": "yarn clean && yarn build",
- "clean": "rm -rf dist && rm -rf coverage",
+ "prepublishOnly": "yarn clean && yarn build && yarn types",
+ "clean": "rm -rf dist && rm -rf types && rm -rf coverage",
"build:ec2-types": "ts-node -T scripts/generate-ec2-types.ts",
"build": "patch-package && webpack",
"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",
"lint": "eslint **/*.ts",
- "lint:types": "tsc",
+ "types": "tsc",
"semantic-release": "semantic-release"
},
"config": {
@@ -47,7 +49,8 @@
}
},
"eslintIgnore": [
- "dist"
+ "dist",
+ "types"
],
"prettier": {
"printWidth": 100,
@@ -129,6 +132,7 @@
"prettier": "^1.18.2",
"prompts": "^2.2.1",
"semantic-release": "^15.13.27",
+ "string-replace-loader": "^2.2.0",
"table": "^5.4.6",
"ts-jest": "^24.1.0",
"ts-loader": "^6.2.1",
diff --git a/scripts/generate-ec2-types.ts b/scripts/generate-ec2-types.ts
index 46236151..ef560250 100644
--- a/scripts/generate-ec2-types.ts
+++ b/scripts/generate-ec2-types.ts
@@ -1,8 +1,8 @@
import { writeFileSync } from 'fs';
import { resolve } from 'path';
-import * as prettier from 'prettier';
+import prettier from 'prettier';
-import { getGlobalSpotPrices } from '../src/lib/lib';
+import { getGlobalSpotPrices } from '../src/lib/core';
const familyGeneral = ['a', 't', 'm'];
@@ -92,7 +92,7 @@ const sortInstances = (i1: string, i2: string): number => {
const getEc2Types = async (): Promise => {
let prices;
try {
- prices = await getGlobalSpotPrices({ silent: true });
+ prices = await getGlobalSpotPrices();
} catch (error) {
console.log(`getGlobalSpotPrices error: ${error}`);
process.exit(1);
diff --git a/scripts/generate-spot-prices-mock-data.ts b/scripts/generate-spot-prices-mock-data.ts
index 357d6928..a346dab3 100644
--- a/scripts/generate-spot-prices-mock-data.ts
+++ b/scripts/generate-spot-prices-mock-data.ts
@@ -1,8 +1,8 @@
-import * as EC2 from 'aws-sdk/clients/ec2';
+import EC2 from 'aws-sdk/clients/ec2';
import { readFileSync, writeFileSync } from 'fs';
import { find, uniqWith, xorWith } from 'lodash';
import { resolve } from 'path';
-import * as yargs from 'yargs';
+import yargs from 'yargs';
import { defaultRegions, Region } from '../src/constants/regions';
diff --git a/src/cli.spec.ts b/src/cli.spec.ts
index c3b34584..46699123 100644
--- a/src/cli.spec.ts
+++ b/src/cli.spec.ts
@@ -160,7 +160,7 @@ describe('cli', () => {
});
describe('test by spawnSync', () => {
- const cliJsPath = resolve(__dirname, '../dist/aws-spot-price.bundle.js');
+ 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();
diff --git a/src/cli.ts b/src/cli.ts
index 906845df..529e230e 100644
--- a/src/cli.ts
+++ b/src/cli.ts
@@ -1,28 +1,33 @@
+import ora from 'ora';
import { sep } from 'path';
-import * as yargs from 'yargs';
+import { table } from 'table';
+import yargs from 'yargs';
+import { ui } from './lib/ui';
import {
allInstances,
+ allProductDescriptions,
+ allRegions,
+ AuthError,
+ awsCredentialsCheck,
+ defaults,
+ Ec2SpotPriceError,
+ generateTypeSizeSetsFromFamily,
+ getGlobalSpotPrices,
instanceFamily,
InstanceFamily,
InstanceFamilyType,
instanceFamilyTypes,
+ instanceOfProductDescription,
InstanceSize,
instanceSizes,
InstanceType,
-} from './constants/ec2-types';
-import {
- allProductDescriptions,
- instanceOfProductDescription,
ProductDescription,
productDescriptionWildcards,
ProductDescriptionWildcards,
-} from './constants/product-description';
-import { allRegions, Region } from './constants/regions';
-import { AuthError, awsCredentialsCheck } from './lib/credential';
-import { defaults, getGlobalSpotPrices } from './lib/lib';
-import { ui } from './lib/ui';
-import { generateTypeSizeSetsFromFamily } from './lib/utils';
+ Region,
+ regionNames,
+} from './module';
export const main = (argvInput?: string[]): Promise =>
new Promise((res, rej): void => {
@@ -198,6 +203,37 @@ export const main = (argvInput?: string[]): Promise =>
const familyTypeSetArray = Array.from(familyTypeSet);
const sizeSetArray = Array.from(sizeSet);
+ let spinnerText: string | undefined;
+ let spinner: ora.Ora | undefined;
+ let onRegionFetch: ((reg: Region) => void) | undefined;
+ let onRegionFetchFail: ((error: Ec2SpotPriceError) => void) | undefined;
+ let onFetchComplete: (() => void) | undefined;
+
+ if (!json && process.env.NODE_ENV !== 'test') {
+ spinner = ora({
+ text: 'Waiting for data to be retrieved...',
+ discardStdin: false,
+ }).start();
+
+ onRegionFetch = (reg: Region): void => {
+ spinnerText = `Retrieved data from ${reg}...`;
+ if (spinner) spinner.text = spinnerText;
+ };
+ onRegionFetchFail = (error: Ec2SpotPriceError): void => {
+ if (spinner)
+ spinner.fail(`Failed to retrieve data from ${error.region}. (${error.code})`);
+ let text = spinnerText;
+ if (!text && spinner) text = spinner.text;
+ spinner = ora({
+ text,
+ discardStdin: false,
+ }).start();
+ };
+ onFetchComplete = (): void => {
+ if (spinner) spinner.succeed('All data retrieved!').stop();
+ };
+ }
+
const results = await getGlobalSpotPrices({
regions: region as Region[],
instanceTypes: instanceType as InstanceType[],
@@ -210,10 +246,36 @@ export const main = (argvInput?: string[]): Promise =>
: undefined,
accessKeyId,
secretAccessKey,
- silent: json,
+ onRegionFetch,
+ onRegionFetchFail,
+ onFetchComplete,
});
- if (json) console.log(JSON.stringify(results, null, 2));
+ if (json) {
+ console.log(JSON.stringify(results, null, 2));
+ } else if (results.length > 0) {
+ console.log(
+ table(
+ results.reduce(
+ (list, price) => {
+ list.push([
+ price.InstanceType,
+ price.SpotPrice,
+ price.ProductDescription,
+ price.AvailabilityZone,
+ price.AvailabilityZone
+ ? regionNames[price.AvailabilityZone.slice(0, -1) as Region]
+ : /* istanbul ignore next */ undefined,
+ ]);
+ return list;
+ },
+ [] as (string | undefined)[][],
+ ),
+ ),
+ );
+ } else {
+ console.log('no matching records found');
+ }
res();
} catch (error) {
diff --git a/src/lib/lib.spec.ts b/src/lib/core.spec.ts
similarity index 97%
rename from src/lib/lib.spec.ts
rename to src/lib/core.spec.ts
index 9239c7e5..cdf36063 100644
--- a/src/lib/lib.spec.ts
+++ b/src/lib/core.spec.ts
@@ -1,7 +1,7 @@
import { SpotPrice } from 'aws-sdk/clients/ec2';
import mockConsole, { RestoreConsole } from 'jest-mock-console';
import { filter } from 'lodash';
-import * as nock from 'nock';
+import nock from 'nock';
import { mockAwsCredentials, mockAwsCredentialsClear } from '../../test/mock-credential-endpoints';
import {
@@ -12,7 +12,7 @@ import { consoleMockCallJoin } from '../../test/utils';
import { InstanceFamilyType, InstanceSize } from '../constants/ec2-types';
import { ProductDescription } from '../constants/product-description';
import { Region } from '../constants/regions';
-import { getGlobalSpotPrices } from './lib';
+import { getGlobalSpotPrices } from './core';
describe('lib', () => {
describe('getGlobalSpotPrices', () => {
@@ -50,7 +50,6 @@ describe('lib', () => {
sizes,
productDescriptions,
limit: 20,
- silent: true,
});
});
@@ -91,7 +90,6 @@ describe('lib', () => {
results = await getGlobalSpotPrices({
familyTypes,
limit: 20,
- silent: true,
});
});
@@ -125,7 +123,6 @@ describe('lib', () => {
results = await getGlobalSpotPrices({
sizes,
limit: 20,
- silent: true,
});
});
@@ -161,7 +158,6 @@ describe('lib', () => {
instanceTypes: ['c5.2xlarge'],
productDescriptions: ['Linux/UNIX'],
limit: 200,
- silent: true,
});
});
@@ -192,7 +188,6 @@ describe('lib', () => {
results = await getGlobalSpotPrices({
priceMax,
- silent: true,
});
});
diff --git a/src/lib/lib.ts b/src/lib/core.ts
similarity index 79%
rename from src/lib/lib.ts
rename to src/lib/core.ts
index e721b6b7..b723c04a 100644
--- a/src/lib/lib.ts
+++ b/src/lib/core.ts
@@ -1,10 +1,8 @@
-import * as EC2 from 'aws-sdk/clients/ec2';
-import * as ora from 'ora';
-import { table } from 'table';
+import EC2 from 'aws-sdk/clients/ec2';
import { InstanceFamilyType, InstanceSize, InstanceType } from '../constants/ec2-types';
import { ProductDescription } from '../constants/product-description';
-import { defaultRegions, Region, regionNames } from '../constants/regions';
+import { defaultRegions, Region } from '../constants/regions';
import { generateInstantTypesFromFamilyTypeSize } from './utils';
const sortSpotPrice = (p1: EC2.SpotPrice, p2: EC2.SpotPrice): number => {
@@ -29,7 +27,7 @@ const sortSpotPrice = (p1: EC2.SpotPrice, p2: EC2.SpotPrice): number => {
return rtn;
};
-class Ec2SpotPriceError extends Error {
+export class Ec2SpotPriceError extends Error {
constructor(message: string, region: Region, code: string) {
super(message) /* istanbul ignore next */;
this.name = 'Ec2SpotPriceError';
@@ -118,9 +116,11 @@ export const getGlobalSpotPrices = async (options?: {
instanceTypes?: InstanceType[];
productDescriptions?: ProductDescription[];
limit?: number;
- silent?: boolean;
accessKeyId?: string;
secretAccessKey?: string;
+ onRegionFetch?: (region: Region) => void;
+ onRegionFetchFail?: (error: Ec2SpotPriceError) => void;
+ onFetchComplete?: Function;
}): Promise => {
const {
familyTypes,
@@ -128,9 +128,11 @@ export const getGlobalSpotPrices = async (options?: {
priceMax,
productDescriptions,
limit,
- silent,
accessKeyId,
secretAccessKey,
+ onRegionFetch,
+ onRegionFetchFail,
+ onFetchComplete,
} = options || {
limit: defaults.limit,
};
@@ -151,16 +153,6 @@ export const getGlobalSpotPrices = async (options?: {
}
}
- let spinner: ora.Ora | undefined;
- let spinnerText: string | undefined;
- /* istanbul ignore if */
- if (!silent && process.env.NODE_ENV !== 'test') {
- spinner = ora({
- text: 'Waiting for data to be retrieved...',
- discardStdin: false,
- }).start();
- }
-
const rtn: EC2.SpotPrice[] = await Promise.all(
regions.map(async region => {
try {
@@ -172,20 +164,13 @@ export const getGlobalSpotPrices = async (options?: {
secretAccessKey,
});
/* istanbul ignore if */
- if (spinner) {
- spinnerText = `Retrieved data from ${region}...`;
- spinner.text = spinnerText;
- }
+ if (onRegionFetch) onRegionFetch(region);
return regionsPrices;
} catch (error) {
/* istanbul ignore if */
if (error instanceof Ec2SpotPriceError) {
- if (spinner) {
- spinner.fail(`Failed to retrieve data from ${error.region}. (${error.code})`);
- spinner = ora({
- text: spinnerText || spinner.text,
- discardStdin: false,
- }).start();
+ if (onRegionFetchFail) {
+ onRegionFetchFail(error);
} else {
throw error;
}
@@ -197,7 +182,7 @@ export const getGlobalSpotPrices = async (options?: {
}),
).then(results => {
/* istanbul ignore if */
- if (spinner) spinner.succeed('All data retrieved!').stop();
+ if (onFetchComplete) onFetchComplete();
return results
.reduce(
(finalList: EC2.SpotPrice[], curList: EC2.SpotPrice[]) => {
@@ -254,32 +239,5 @@ export const getGlobalSpotPrices = async (options?: {
// limit output
if (limit && rtn.length > limit) rtn.splice(limit);
- // log output
- if (!silent) {
- if (rtn.length > 0) {
- console.log(
- table(
- rtn.reduce(
- (list, price) => {
- list.push([
- price.InstanceType,
- price.SpotPrice,
- price.ProductDescription,
- price.AvailabilityZone,
- price.AvailabilityZone
- ? regionNames[price.AvailabilityZone.slice(0, -1) as Region]
- : /* istanbul ignore next */ undefined,
- ]);
- return list;
- },
- [] as (string | undefined)[][],
- ),
- ),
- );
- } else {
- console.log('no matching records found');
- }
- }
-
return rtn;
};
diff --git a/src/lib/credential.spec.ts b/src/lib/credential.spec.ts
index 693be636..8dd4f740 100644
--- a/src/lib/credential.spec.ts
+++ b/src/lib/credential.spec.ts
@@ -1,5 +1,5 @@
import mockConsole, { RestoreConsole } from 'jest-mock-console';
-import * as nock from 'nock';
+import nock from 'nock';
import { mockAwsCredentials, mockAwsCredentialsClear } from '../../test/mock-credential-endpoints';
import { consoleMockCallJoin } from '../../test/utils';
diff --git a/src/lib/credential.ts b/src/lib/credential.ts
index f7bf8e80..2b986d17 100644
--- a/src/lib/credential.ts
+++ b/src/lib/credential.ts
@@ -1,4 +1,4 @@
-import STS = require('aws-sdk/clients/sts');
+import STS from 'aws-sdk/clients/sts';
type AuthErrorCode = 'CredentialsNotFound' | 'UnAuthorized';
diff --git a/src/module.ts b/src/module.ts
new file mode 100644
index 00000000..fadea04f
--- /dev/null
+++ b/src/module.ts
@@ -0,0 +1,7 @@
+// export { getGlobalSpotPrices } from './lib/core';
+export * from './lib/core';
+export * from './lib/credential';
+export * from './lib/utils';
+export * from './constants/ec2-types';
+export * from './constants/product-description';
+export * from './constants/regions';
diff --git a/test/__snapshots__/lib/lib.spec.ts.snap b/test/__snapshots__/lib/core.spec.ts.snap
similarity index 100%
rename from test/__snapshots__/lib/lib.spec.ts.snap
rename to test/__snapshots__/lib/core.spec.ts.snap
diff --git a/test/mock-credential-endpoints.ts b/test/mock-credential-endpoints.ts
index 81a8aa8c..3de86c46 100644
--- a/test/mock-credential-endpoints.ts
+++ b/test/mock-credential-endpoints.ts
@@ -1,6 +1,6 @@
import { config } from 'aws-sdk';
-import * as fs from 'fs';
-import * as nock from 'nock';
+import fs from 'fs';
+import nock from 'nock';
import { sep } from 'path';
let readFileSyncMock: jest.SpyInstance;
diff --git a/test/mock-ec2-endpoints.ts b/test/mock-ec2-endpoints.ts
index 2885f6cc..9ef53a0e 100644
--- a/test/mock-ec2-endpoints.ts
+++ b/test/mock-ec2-endpoints.ts
@@ -1,7 +1,7 @@
import { SpotPrice } from 'aws-sdk/clients/ec2';
import { readFileSync } from 'fs';
import { filter } from 'lodash';
-import * as nock from 'nock';
+import nock from 'nock';
import { resolve } from 'path';
import { parse } from 'querystring';
diff --git a/tsconfig.json b/tsconfig.json
index fff0241f..88ae9eb0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,23 +1,29 @@
{
"compilerOptions": {
- "module": "commonjs",
- "target": "es5",
- "lib": ["es5"],
+ "module": "esnext",
+ "target": "esnext",
+ "lib": ["esnext"],
"moduleResolution": "node",
"strict": true,
"strictPropertyInitialization": false,
"sourceMap": true,
"downlevelIteration": true,
"rootDir": "src",
- "noEmit": true
+ "emitDeclarationOnly": true,
+ "declaration": true,
+ "declarationDir": "types",
+ "esModuleInterop": true
},
"files": [
"src/cli.ts",
+ "src/module.ts",
"src/constants/ec2-types.ts",
"src/constants/product-description.ts",
"src/constants/regions.ts",
- "src/lib/lib.ts",
- "src/lib/ui.ts"
+ "src/lib/core.ts",
+ "src/lib/credential.ts",
+ "src/lib/ui.ts",
+ "src/lib/utils.ts"
],
"exclude": ["node_modules"]
}
diff --git a/webpack.config.js b/webpack.config.js
index 0be276cb..b514a9f3 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -2,14 +2,16 @@ const path = require('path');
module.exports = {
mode: 'production',
- entry: path.resolve(__dirname, 'src/cli.ts'),
+ entry: {
+ cli: path.resolve(__dirname, 'src/cli.ts'),
+ module: path.resolve(__dirname, 'src/module.ts'),
+ },
resolve: {
extensions: ['.js', '.json', '.ts'],
},
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, 'dist'),
- filename: 'aws-spot-price.bundle.js',
},
stats: {
warningsFilter: [/node_modules\/yargs/],
@@ -17,6 +19,14 @@ module.exports = {
target: 'node',
module: {
rules: [
+ {
+ test: /cli\.ts$/,
+ loader: 'string-replace-loader',
+ options: {
+ search: "from './module'",
+ replace: "from '../dist/module'",
+ },
+ },
{
test: /\.tsx?$/,
use: [
@@ -30,4 +40,5 @@ module.exports = {
},
],
},
+ externals: [/dist\/module$/],
};
diff --git a/yarn.lock b/yarn.lock
index 051dbc4c..135c68c9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8432,6 +8432,14 @@ string-length@^2.0.0:
astral-regex "^1.0.0"
strip-ansi "^4.0.0"
+string-replace-loader@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/string-replace-loader/-/string-replace-loader-2.2.0.tgz#0a0e6543fcec783d85c353a3e96a23872d45a94f"
+ integrity sha512-Ukt4ZC8+xVWdBRut3/iwnPJCNL1yV8AbVKXn8UcWdYrHgtuW4UDDAbBSi/J/CQDEWQBt824AJvPYahF23eJLRg==
+ dependencies:
+ loader-utils "^1.2.3"
+ schema-utils "^1.0.0"
+
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"