Skip to content

Commit

Permalink
Merge pull request #164 from shelfio/feature/typescript-support
Browse files Browse the repository at this point in the history
Added typescript support!
  • Loading branch information
harazdovskiy authored Aug 9, 2022
2 parents f59e20c + d6894e3 commit e20954c
Show file tree
Hide file tree
Showing 17 changed files with 273 additions and 114 deletions.
2 changes: 2 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ jobs:
steps:
- checkout
- run: yarn
- run: yarn build
- run: yarn test

test_with_db:
Expand All @@ -20,6 +21,7 @@ jobs:
steps:
- checkout
- run: yarn
- run: yarn build
- run: yarn test

workflows:
Expand Down
3 changes: 3 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
lib/
renovate.json
tsconfig.json
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.idea/
coverage/
node_modules/
lib/
temp
yarn.lock
*.log
Expand Down
7 changes: 6 additions & 1 deletion jest-dynamodb-config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
module.exports = {
/**
* @type {import('./lib/types').Config}
*/
const config = {
tables: [
{
TableName: `files`,
Expand All @@ -16,3 +19,5 @@ module.exports = {
port: 8000,
options: ['-sharedDb'],
};

module.exports = config;
8 changes: 2 additions & 6 deletions jest-preset.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
const {resolve} = require('path');
const preset = require('./lib');

module.exports = {
globalSetup: resolve(__dirname, './setup.js'),
globalTeardown: resolve(__dirname, './teardown.js'),
testEnvironment: resolve(__dirname, './environment.js'),
};
module.exports = preset;
29 changes: 19 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@shelf/jest-dynamodb",
"version": "3.2.0",
"version": "3.3.0",
"description": "Run your tests using Jest & DynamoDB local",
"keywords": [
"dynamodb",
Expand All @@ -17,23 +17,25 @@
"url": "shelf.io"
},
"files": [
"environment.js",
"jest-preset.js",
"setup.js",
"teardown.js",
"wait-for-localhost.js"
"lib/"
],
"scripts": {
"build": "rm -rf lib/ && yarn build:types && babel src --out-dir lib --ignore '**/*.test.ts' --extensions '.ts'",
"build:types": "tsc --emitDeclarationOnly --declaration --isolatedModules false --declarationDir lib",
"coverage": "jest --coverage",
"lint": "eslint . --ext .js,.ts,.json --fix",
"lint:ci": "eslint . --ext .js,.ts,.json",
"test": "export ENVIRONMENT=local && jest ."
"prepack": "yarn build",
"test": "export ENVIRONMENT=local && jest tests",
"type-check": "tsc --noEmit",
"type-check:watch": "npm run type-check -- --watch"
},
"lint-staged": {
"*.{html,md,yml}": [
"prettier --write"
],
"*.{js,json}": [
"*.{ts,js,json}": [
"eslint --fix"
]
},
Expand All @@ -53,10 +55,17 @@
"dynamodb-local": "0.0.31"
},
"devDependencies": {
"@shelf/babel-config": "1.0.2",
"@shelf/eslint-config": "2.18.0",
"@babel/cli": "7.18.9",
"@babel/core": "7.18.9",
"@shelf/babel-config": "1.2.0",
"@shelf/eslint-config": "2.22.0",
"@shelf/prettier-config": "1.0.0",
"eslint": "8.20.0",
"@shelf/tsconfig": "0.0.8",
"@types/aws-sdk": "2.7.0",
"@types/cwd": "^0.10.0",
"@types/jest": "28.1.3",
"@types/node": "16",
"eslint": "8.21.0",
"husky": "8.0.1",
"jest": "28.1.3",
"lint-staged": "13.0.3",
Expand Down
15 changes: 13 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ Array of createTable params.

Port number. The default port number is `8000`.

##### hostname

- Type: `string`
- Required: `false`

Port number. The default hostname number is `localhost`.

##### options

- Type: `string[]`
Expand Down Expand Up @@ -72,9 +79,12 @@ The default value is defined at https://github.com/rynop/dynamodb-local/blob/2e6
#### 2.2 Examples

You can set up tables as an object:

> Whole list of config properties can be found [here](https://github.com/shelfio/jest-dynamodb/blob/6c64dbd4ee5a68230469ea14cbfb814470521197/src/types.ts#L80-L87)
```js
module.exports = {
/**
* @type {import('@shelf/jest-dynamodb/lib').Config}')}
*/
const config = {
tables: [
{
TableName: `files`,
Expand All @@ -86,6 +96,7 @@ module.exports = {
],
port: 8000,
};
module.exports = config;
```

Or as an async function (particularly useful when resolving DynamoDB setup dynamically from `serverless.yml`):
Expand Down
73 changes: 0 additions & 73 deletions setup.js

This file was deleted.

11 changes: 8 additions & 3 deletions environment.js → src/environment.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
/* eslint-disable no-console */
const {TestEnvironment} = require('jest-environment-node');
import type {EnvironmentContext} from '@jest/environment';
import type {JestEnvironmentConfig} from '@jest/environment';
import {TestEnvironment} from 'jest-environment-node';

const debug = require('debug')('jest-dynamodb');

module.exports = class DynamoDBEnvironment extends TestEnvironment {
constructor(config) {
super(config);
constructor(config: JestEnvironmentConfig, context: EnvironmentContext) {
super(config, context);
}

async setup() {
Expand All @@ -19,7 +22,9 @@ module.exports = class DynamoDBEnvironment extends TestEnvironment {
await super.teardown();
}

// @ts-ignore
runScript(script) {
// @ts-ignore
return super.runScript(script);
}
};
9 changes: 9 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {resolve} from 'path';

export * from './types';

export default {
globalSetup: resolve(__dirname, './setup.js'),
globalTeardown: resolve(__dirname, './teardown.js'),
testEnvironment: resolve(__dirname, './environment.js'),
};
91 changes: 91 additions & 0 deletions src/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import type {ListTablesCommandOutput} from '@aws-sdk/client-dynamodb/dist-types/commands/ListTablesCommand';
import type {argValues} from 'dynamodb-local';
import DynamoDbLocal from 'dynamodb-local';
import {resolve} from 'path';
import cwd from 'cwd';
import {DynamoDB} from '@aws-sdk/client-dynamodb';
import type {CreateTableCommandInput} from '@aws-sdk/client-dynamodb';
import type {Config} from './types';
import waitForLocalhost from './utils/wait-for-localhost';

const debug = require('debug')('jest-dynamodb');

const DEFAULT_PORT = 8000;
const DEFAULT_HOST = 'localhost';
const DEFAULT_OPTIONS: argValues[] = ['-sharedDb'];

export default async function () {
const {
tables: newTables,
clientConfig,
installerConfig,
port: port = DEFAULT_PORT,
hostname: hostname = DEFAULT_HOST,
options: options = DEFAULT_OPTIONS,
} = await getConfig();

const dynamoDB = new DynamoDB({
endpoint: `http://${hostname}:${port}`,
tls: false,
region: 'local-env',
credentials: {
accessKeyId: 'fakeMyKeyId',
secretAccessKey: 'fakeSecretAccessKey',
},
...clientConfig,
});

global.__DYNAMODB_CLIENT__ = dynamoDB;

try {
const promises: (Promise<ListTablesCommandOutput> | Promise<void>)[] = [
dynamoDB.listTables({}),
];

if (!global.__DYNAMODB__) {
promises.push(waitForLocalhost(port, hostname));
}

const [TablesList] = await Promise.all(promises);
const tableNames = TablesList?.TableNames;

if (tableNames) {
await deleteTables(dynamoDB, tableNames);
}
} catch (err) {
// eslint-disable-next-line no-console
debug(`fallback to launch DB due to ${err}`);

if (installerConfig) {
DynamoDbLocal.configureInstaller(installerConfig);
}

if (!global.__DYNAMODB__) {
debug('spinning up a local ddb instance');

global.__DYNAMODB__ = await DynamoDbLocal.launch(port, null, options);
debug(`dynamodb-local started on port ${port}`);

await waitForLocalhost(port, hostname);
}
}
debug(`dynamodb-local is ready on port ${port}`);

await createTables(dynamoDB, newTables);
}

function createTables(dynamoDB: DynamoDB, tables: CreateTableCommandInput[]) {
return Promise.all(tables.map(table => dynamoDB.createTable(table)));
}

function deleteTables(dynamoDB: DynamoDB, tableNames: string[]) {
return Promise.all(tableNames.map(tableName => dynamoDB.deleteTable({TableName: tableName})));
}

async function getConfig(): Promise<Config> {
const path = process.env.JEST_DYNAMODB_CONFIG || resolve(cwd(), 'jest-dynamodb-config.js');
const config = require(path);
debug('config:', config);

return typeof config === 'function' ? await config() : config;
}
11 changes: 8 additions & 3 deletions teardown.js → src/teardown.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const DynamoDbLocal = require('dynamodb-local');
import DynamoDbLocal from 'dynamodb-local';
import type {JestArgs} from './types';

const debug = require('debug')('jest-dynamodb');

module.exports = async function (jestArgs) {
export default async function (jestArgs: JestArgs) {
// eslint-disable-next-line no-console
debug('Teardown DynamoDB');

Expand All @@ -14,6 +16,9 @@ module.exports = async function (jestArgs) {
} else {
const dynamoDB = global.__DYNAMODB_CLIENT__;
const {TableNames: tableNames} = await dynamoDB.listTables({});
await Promise.all(tableNames.map(tableName => dynamoDB.deleteTable({TableName: tableName})));

if (tableNames?.length) {
await Promise.all(tableNames.map(tableName => dynamoDB.deleteTable({TableName: tableName})));
}
}
};
Loading

0 comments on commit e20954c

Please sign in to comment.