You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Built with :heart: by the crew from [https://www.shiftcode.ch](shiftcode).
9
+
Abstracts away the complexity of the low level aws dynamosdk. Provides an easy to use fluent api to for requests and supports typescript decorators,
10
+
to define some metadata for your models. You don't need to care about the mapping of javascript types to their dynamo types any more. We got you covered.
10
11
11
-
## Purpose
12
+
Checkout the full technical api documentation [here](https://shiftcode.github.io/dynamo-easy/).
12
13
13
-
The official Amazon Dynamo SDK for javascript has a pretty low level api, where some deeper knowledge about all the possible options is required.
14
-
This Library provides an easy to use, descriptive, chainable api to execute dynamoDb requests. It also provides decorators to define how a type should be mapped
15
-
to dynamodb. Supporting simple types like String, Number, Boolean, Binary to more complex types like custom classes, momentJs dates.
16
-
17
-
Checkout the full api documentation [https://shiftcode.github.io/dynamo-easy/](here).
18
-
19
-
# What this library does not provide
20
-
API to setup tables (we use cloudformation on our side for infrastructur setup, so this was not a need for us)
14
+
Built with :heart: by the crew from [shiftcode](https://www.shiftcode.ch).
21
15
22
16
# Get Started
23
-
Usage with Angular (>4) checkout our angular-service. [TODO](TODO)
24
-
25
-
Basic Example:
26
17
```
27
18
@Model()
28
19
class Person{
@@ -58,126 +49,87 @@ dynamoStore.scan()
58
49
59
50
```
60
51
61
-
# Decorators
62
-
Decorators define how on object should be mapped to dynamodb also defining indexes and properties which are used as partition keys
63
-
Use the class <MetadataHelper> to read the informations defined by decorators.
64
-
65
-
Checkout the full [https://shiftcode.github.io/dynamo-easy/](documentation).
66
-
67
-
-----
68
-
69
-
To map an js object into the attribute map required by dynamodb requests, we implement our very oppinionated custom mapper.
70
-
We use the DynamoDB Document Mapper to map all «default» types to dynamodb attribute values.
71
-
72
-
There are some custom requirements for these cases:
73
-
74
-
- MomentJs Dates
75
-
- Use ES6 Map, Set types
76
-
77
-
Mapper Strategy:
78
-
79
-
-> To DB
80
-
1) check if we have some property metadata
81
-
82
-
YES NO
83
-
84
-
isCustomType document client can map (check with typeof propertyValue for additional security)
85
-
86
-
YES NO
87
-
88
-
custom mapping document client can map
89
-
90
-
-> From DB
91
-
92
-
-----
93
-
52
+
Want to use this library with Angular (>4) [checkout our angular-service](TODO).
94
53
95
-
Decorators are used to add some metadata to our model classes required by the mapper for some special cases.
54
+
# Decorators
55
+
Decorators are used to add some metadata to our model classes, relevant to our javascript-to-dynamo mapper.
96
56
97
-
This is an experimental feature and requires to set the
57
+
This is an experimental feature and requires to set the following typescript compiler options:
98
58
99
59
- "experimentalDecorators": true
100
60
- "emitDecoratorMetadata": true
101
61
102
-
typescript compiler options.
103
-
104
62
Additionally we rely on the reflect-metadata (https://www.npmjs.com/package/reflect-metadata) library for reflection api.
105
63
106
-
To get started with decorators just add a @Model() Decorator to any ts class. By default this enables the custom mapping functionality
107
-
and will get you started to work with Dynamo DB and simple types (like String, Number, Boolean etc. but no custom classes for example)
64
+
To get started with decorators just add a [@Model()](https://shiftcode.github.io/dynamo-easy/modules/_decorator_impl_model_model_decorator_.html) Decorator to any typescript class.
65
+
66
+
If you need to read the metadata by hand for some purpose, use the [MetadataHelper](https://shiftcode.github.io/dynamo-easy/classes/_decorator_metadata_metadata_helper_.metadatahelper.html) to read the informations.
108
67
109
68
We make heavy usage of compile time informations about our models and the property types.
110
69
Here is a list of the types that can be retrieved from compile time information for the key design:type. (The metadata will only be added if at least one decorator is
111
70
present on a property)
112
71
113
-
String
114
-
Number
115
-
Boolean
116
-
Array (no generics)
117
-
Custom Types
118
-
119
-
Map / Set will be Object
72
+
- String
73
+
- Number
74
+
- Boolean
75
+
- Array (no generics)
76
+
- Custom Types
77
+
- ES6 types like Set, Map will be mapped to Object when calling for the type via Reflect.get(design:type), so we need some extra info.
120
78
121
79
Generic information is never available due to some serialization limitations at the time of writing.
122
80
123
-
ES6 types like Set, Map will be mapped to Object when calling for the type via Reflect.get(design:type), so we need some extra info.
81
+
## A word on Collections (Array & Set)
124
82
125
-
##### Collections
126
-
127
-
#Array
83
+
###Array
128
84
Javascript Arrays with a a items of type String, Number or Binary will be mapped to a S(et) type, by default all other types are mapped to L(ist) type.
129
85
If an item of an Array has a complex type the type can be defined using the @TypedArray() Decorator.
130
86
131
-
#Set
132
-
es6 Set types will be marshalled to dynamoDb set type if the type of the set is supported, if the type is not supported it will be
87
+
###Set
88
+
ES6 Set types will be marshalled to dynamoDb set type if the type of the set is supported, if the type is not supported it will be
133
89
marshalled to an dynamoDB List.
134
90
135
91
When one of the following decorators is added, the value is marshalled to a List type.
Here is the rule how a table name is built `${kebabCase(modelName)}s` so for a model called Product the table will be named products, this is a default implementation.
140
-
To Provide your own logic you can implement a TableNameResolver function and give it to the DynamoStore class when implementing a new instance.
141
98
99
+
There are two possibilities to change the name:
142
100
143
-
**Custom TableName**
144
-
@Model({tableName: tableName})
101
+
- override the name using the tableName parameter @Model({tableName: tableName})
102
+
- provide a TableNameResolver function when instantiating a DynamoStore. This method will receive the default table name
103
+
(either resolved using the model name or custom value when a tableName was provided in @Model decorator)
145
104
105
+
# Mapper
146
106
147
-
####Types
107
+
## Types
148
108
149
-
Simple Type (no decorators requried to work)
109
+
We do the mapping from javascript objects to dynamodb types for you in requests and responses
110
+
111
+
Simple Type (no decorators required to work)
150
112
- String
151
113
- Number
152
114
- Boolean
153
115
- Null
154
116
- Array
155
-
156
-
- Date (moment) is mapped by convention (see TODO:addLink Dates)
117
+
- Date (we only support MomentJS)
157
118
158
119
Complex Types (properties with these types need some decorators to work properly)
159
120
- Set<simpleType | complexType>
160
121
- Map
161
122
- Array<complexType>
162
123
163
-
#####Date #####
164
-
Two Date types are supported. Default JS Date and moment dates.
124
+
## Date
125
+
Right now we only support (MomentJS)[http://momentjs.com/] Dates.
165
126
166
-
The type defines how a value will be mapped. Types can be defined using decorators (for complex types) or we use one of the following methods:
167
-
fromDB -> use default for DynamoDB type (see type table)
168
-
toDB -> use property value to resolve the type
169
-
170
-
design:type
171
-
String, Number, Boolean, Undefined, Object
172
-
173
-
unsupported
174
-
Set, Map, Date, moment.Moment
127
+
If you want to explicitly mark a property to be a Date use the @Date() decorator. If we find a moment value we automatically map it to a String (using ISO-8601 format).
128
+
When coming from db we do a regex test for ISO-8601 format and map it back to a moment object.
175
129
176
130
# Requests API
177
-
178
-
To start making requests create an instance of [TODO add link](DynamoStore) and execute the desired operation using the provided api.
179
-
We support all the common dynamodb operations
180
-
See for a the [TODO add link](full documentation).
131
+
To start making requests create an instance of [DynamoStore](https://shiftcode.github.io/dynamo-easy/classes/_dynamo_dynamo_store_.dynamostore.html) and execute the desired operation using the provided api.
132
+
We support all the common dynamodb operations.
181
133
182
134
The request api has support for the following operations:
183
135
@@ -195,9 +147,9 @@ need some more info.
195
147
There is always the possibility to access the Params object directly to add values which are not covered with our api.
196
148
197
149
# Authentication
198
-
In a real world scenario you'll have some kind of authentication to protect your dynamodb ressources. You can customize on how to authenticate when giving a custom
199
-
SessionValidityEnsurer function to the dynamo store when creating a new instance.
200
-
The default implementation is a no-op.
150
+
In a real world scenario you'll have some kind of authentication to protect your dynamodb ressources. You can customize on how to authenticate when providing a custom
151
+
SessionValidityEnsurer function to the DynamoStore when creating a new instance.
152
+
The default implementation is a no-op function.
201
153
202
154
## Session Validity Ensurer
203
155
Here is an example of an implementation using amazon cognito
@@ -225,64 +177,39 @@ function sessionValidityEnsurer(): Observable<>{
The usage of ExpressionAttributeNames is not required, but due to the fact that there are a lot of keywords which could not be used in an expression (blacklist)[http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html],
241
-
we replace the attribute names always with a variable (starting with the '#' sign)
242
-
243
-
244
-
----
245
-
246
-
247
-
By default we create a substitution placeholder for all the attributes, just to not implement a blacklist with reserved words in the context of aws dynamodb.
By default we create a substitution placeholder for all the attributes, just to not implement a [blacklist](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ReservedWords.html) with reserved words in the context of aws dynamodb.
248
182
249
183
attributename: age
250
184
185
+
```
186
+
expression: '#age = :age'
251
187
attributeExpressionNames: {'#age': 'age'}
252
188
attributeExpressionValues: {':age': {N: '10'}}
253
-
expression: '#age = :age'
189
+
```
254
190
255
191
this works seemlesly for top level attribtues, but if we wanna build an expression for where the attribute needs to be accessed with a document path, we need some special logic
we can't use #personAge: 'person.age' because if the dot is part of an attribute name it is not treated as a metacharacter compared to when using directly in expression, so
200
+
we can't use #personAge as a placeholder for 'person.age' because if the dot is part of an attribute name it is not treated as a metacharacter compared to when using directly in expression, so
263
201
the above solution needs to be used
264
202
265
203
these are the accessor rules for nested attribute types
266
-
-[n]—for list elements
267
-
- . (dot)—for map elements
204
+
-[n] — for list elements
205
+
- . (dot) — for map elements
268
206
269
-
###Pagination
207
+
## Pagination
270
208
TODO
271
209
272
-
### Primary Key
273
-
274
-
To be clear about the used naming for keys, here is how we use it (same as in the official aws documentation):
275
-
276
-
DynamoDb has two key types **Partition Key** (hashkey - dynamodb internally uses a hash function to evenly distribute data items across partitions) and **Sort Key** (rangekey)
277
-
The primary key can either be simple (only a partition key) or composite (combination of partition and sort key)
278
-
279
-
280
-
## Contribution
281
-
282
-
## Development
283
-
284
-
### NPM scripts
210
+
# Development
285
211
212
+
## NPM scripts
286
213
-`npm t`: Run test suite
287
214
-`npm start`: Runs `npm run build` in watch mode
288
215
-`npm run test:watch`: Run test suite in [interactive watch mode](http://facebook.github.io/jest/docs/cli.html#watch)
@@ -291,34 +218,28 @@ The primary key can either be simple (only a partition key) or composite (combin
291
218
-`npm run lint`: Lints code
292
219
-`npm run commit`: Commit using conventional commit style ([husky](https://github.com/typicode/husky) will tell you to use it if you haven't :wink:)
293
220
294
-
### Automatic releases
295
-
296
-
We use automatic releases with Semantic Versioning, follow these simple steps.
297
-
298
-
semantic-release setup
299
-
300
-
From now on, you'll need to use `npm run commit`, which is a convenient way to create conventional commits.
221
+
## Automatic releases
222
+
Use the npm comand `npm run commit`, which is a convenient way to create conventional commits. Those messages are used to run [semantic releases](https://github.com/semantic-release/semantic-release),
223
+
which publishes our code automatically on github and npm, plus generates automatically a changelog. This setup is highly influenced by [Kent C. Dodds course on egghead.io](https://egghead.io/courses/how-to-write-an-open-source-javascript-library)
301
224
302
-
Automatic releases are possible thanks to [semantic release](https://github.com/semantic-release/semantic-release), which publishes our code automatically on github and npm, plus generates automatically a changelog. This setup is highly influenced by [Kent C. Dodds course on egghead.io](https://egghead.io/courses/how-to-write-an-open-source-javascript-library)
225
+
## Git Hooks
226
+
We use 2 git hooks:
303
227
304
-
### Git Hooks
228
+
`precommit`
229
+
- to format the code with Prettier :nail_care: before sending it to the git repo.
230
+
- to check if the commit message follows a [conventional commit message](https://github.com/conventional-changelog/conventional-changelog)
305
231
306
-
There is already set a `precommit` hook for formatting your code with Prettier :nail_care:
307
232
308
-
By default, there are 2 disabled git hooks. They're set up when you run the `npm run semantic-release-prepare` script. They make sure:
309
-
- You follow a [conventional commit message](https://github.com/conventional-changelog/conventional-changelog)
310
-
- Your build is not gonna fail in [Travis](https://travis-ci.org) (or your CI server), since it's runned locally before `git push`
311
-
312
-
This makes more sense in combination with [automatic releases](#automatic-releases)
233
+
`prepush`
234
+
- if the code can be built running npm run build
235
+
- if all the tests pass
313
236
314
237
## Credits
315
-
316
238
[https://github.com/alexjoverm/typescript-library-starter](https://github.com/alexjoverm/typescript-library-starter) For the awesome project which helps to scaffold, develop and build a typescript library project
317
239
[https://github.com/ryanfitz/vogels](https://github.com/ryanfitz/vogels) - To get an idea on how to build the chainable api
318
240
[http://densebrain.github.io/typestore/](http://densebrain.github.io/typestore/) - Thats where the base idea on how to implement the model decorators came came from
319
241
320
242
## Contributors
321
-
322
243
Made with :heart: by [@michaelwittwer](https://github.com/michaelwittwer) and all these wonderful contributors ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
323
244
324
245
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
Copy file name to clipboardExpand all lines: package.json
+2-2Lines changed: 2 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
{
2
2
"name": "dynamo-easy",
3
3
"version": "0.0.1-alpha.1",
4
-
"description": "",
4
+
"description": "Use the power of typescript to define your object mapping when using dynamodb. This library also provides a fluent api for easy interaction with dynamodb.",
0 commit comments