Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tgandrews committed Oct 7, 2020
0 parents commit d1167c0
Show file tree
Hide file tree
Showing 20 changed files with 9,956 additions and 0 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
21 changes: 21 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org

root = true


[*]

# Change these settings to your own preference
indent_style = space
indent_size = 2

# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
26 changes: 26 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: PR

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node: ["12"]
name: Node ${{ matrix.node }} sample
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- run: npm ci
- run: npm run format -- --check
- run: npm run test -- --coverage
41 changes: 41 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Release

on:
release:
types: [published]

jobs:
release:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Read .nvmrc
run: echo "##[set-output name=nvmrc;]$(cat .nvmrc)"
id: nvm

- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: ${{ steps.nvm.outputs.nvmrc }}

- name: Install dependencies
run: npm ci

- name: Build the code
run: npm run build

- name: Get the latest release
id: latest
uses: pozetroninc/github-action-get-latest-release@master
with:
owner: tgandrews
repo: omanyd
excludes: prerelease, draft

- name: Publish to npm
uses: npm publish --tag $VERSION
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
VERSION: ${{ steps.latest.ouputs.release }}
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
*.node
node_modules/
build/
Debug/
Release/
npm-debug.log
tmp
covreporter/
coverage/
.tern-port
lib
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.gitignore
.prettierignore
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"trailingComma": "es5"
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"typescript.tsdk": "node_modules/typescript/lib"
}
151 changes: 151 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Omanyd

A simple but production ready dynamodb mapper.

## Features

- Simplified data modeling and mapping to DynamoDB types
- Data validation using [Joi](https://joi.dev/)
- [Autogenerating IDs](#Creating)
- Complete typescript typings

### Missing features

- Parallel scans
- Paging
- Complex querying
- Number and binary sets
- Boolean types
- Date types
- Lists

## Installation

npm: `npm install omanyd`
yarn: `yarn add omanyd`

## Getting Started

Set the AWS environment variables before running the program

```bash
AWS_REGION="REGION" \
AWS_ACCESS_KEY_ID="ACCESS KEY ID" \
AWS_SECRET_ACCESS_KEY="SECRET ACCESS KEY" \
node app.js
```

These will already by defined for you if you are running in ec2 or lambda.

For running locally we recommend using the official dynamodb docker container and then providing
an additional environment variable to override the dynamodb url. `DYNAMODB_URL=http://localhost:8000`

### Define a Model

Models are defined through `define`. You provide the table name, schema and hashKey definition.

```ts
import omanyd from "omanyd";
import Joi from "joi";

interface Tweet {
id: string;
content: string;
}
const TweetStore = omanyd.define<Tweet>("Tweet", {
hashKey: "TweetID",
schema: {
id: omanyd.types.id(),
content: Joi.string(),
},
});
```

### Create tables (for testing)

You can create tables for use locally during tests but should be managing this with a proper tool
[IaC](https://en.wikipedia.org/wiki/Infrastructure_as_code) for production.

This expects all stores defined using the define method above before use. It will skip creating a
table if it already exists so this cannot be used for modifying a table definition.

```js
import { createTables } from "omanyd";

await createTables();
```

### Delete Tables (for testing)

You can delete tables for use locally during tests but should be managing this with a proper tool
[IaC](https://en.wikipedia.org/wiki/Infrastructure_as_code) for production.

This expects all stores defined using the define method above before use. It then clears all saved
definitions so they can be redefined.

```ts
import { deleteTables } from "omanyd";

await deleteTables();
```

### Creating

Once you have defined your store you can create models from it and unless you provide an id then one
will be created for you automatically as the `omanyd.types.id()` was used in the [definition above](#Define%20a%20model)

```ts
const tweet = TweetStore.create({ content: "My first tweet" });
console.log(tweet);
/*
* { id: "958f2b51-774a-436a-951e-9834de3fe559", content: "My first tweet" }
*/
```

### Reading one - getting by hash key

Now that we have some data in the store we can now read it. The quickest way is reading directly by the hash key.

```ts
const readTweet = TweetStore.getByHashKey(
"958f2b51-774a-436a-951e-9834de3fe559"
);
console.log(readTweet);
/*
* { id: "958f2b51-774a-436a-951e-9834de3fe559", content: "My first tweet" }
*/
```

### Reading many - scanning

If we want all of the items in the store we can use a scan. DynamoDB scans come with some [interesting caveats](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html).

```ts
await Promise.all([
TweetStore.create({ content: "My second tweet" }),
TweetStore.create({ content: "My third tweet" }),
TweetStore.create({ content: "My fourth tweet" }),
]);

const tweets = await TweetStore.scan();

console.log(tweets);
/* [
* { id: "958f2b51-774a-436a-951e-9834de3fe559", content: "My first tweet" },
* { id: "aa6ea347-e3d3-4c73-8960-709fa47e3a4c", content: "My second tweet" },
* { id: "9cd6b18a-eafd-49c2-8f0f-d3bf8e75c26e", content: "My third tweet" },
* { id: "fc446fcd-d65a-4ae2-ba9f-6bd94aae8705", content: "My fourth tweet" }
* ]
*/
```

### History

Omanyd was originally inspired by [dynamodb](https://www.npmjs.com/package/dynamodb) and [dynamoose](https://www.npmjs.com/package/dynamoose)

### Support

Omanyd is provided as-is, free of charge. For support, you have a few choices:

- Ask your support question on [Stackoverflow.com](http://stackoverflow.com), and tag your question with **omanyd**.
- If you believe you have found a bug in omanyd, please submit a support ticket on the [Github Issues page for dynamo](http://github.com/tgandrews/omanyd/issues).
23 changes: 23 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
roots: ["<rootDir>/src"],
testMatch: ["**/*.test.ts"],
transform: {
"^.+\\.tsx?$": "ts-jest",
},
testEnvironment: "node",
coverageThreshold: {
global: {
branches: 75,
functions: 90,
lines: 90,
statements: 90,
},
},
globals: {
"ts-jest": {
diagnostics: {
warnOnly: true,
},
},
},
};

0 comments on commit d1167c0

Please sign in to comment.