Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
"test": "jest",
"test:ci": "jest --coverage --no-cache",
"test:watch": "jest --watch",
"tslint:custom-rule:build": "tsc ./tools/tslint/noDynamoNamedImportRule.ts",
"tslint:custom-rule:test": "tslint --test ./tools/tslint/test",
"prettier": "prettier --write --config ./.prettierrc.yml '{src,test}/**/*.ts'"
},
"devDependencies": {
Expand Down Expand Up @@ -69,6 +71,7 @@
"tsc-watch": "^1.0.31",
"tslint": "^5.12.0",
"tslint-config-prettier": "^1.17.0",
"tsutils": "^3.6.0",
"typedoc": "^0.13.0",
"typescript": "^3.2.2",
"uuid": "^3.3.2"
Expand Down
6 changes: 3 additions & 3 deletions src/decorator/impl/index/util.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { KeyType } from 'aws-sdk/clients/dynamodb'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { PropertyMetadata } from '../../metadata/property-metadata.model'
import { initOrUpdateProperty } from '../property/init-or-update-property.function'
import { KEY_PROPERTY } from '../property/key-property.const'
import { IndexType } from './index-type.enum'

export interface IndexData {
name: string
keyType: KeyType
keyType: DynamoDB.KeyType
}

export function initOrUpdateIndex(indexType: IndexType, indexData: IndexData, target: any, propertyKey: string): void {
Expand Down Expand Up @@ -34,7 +34,7 @@ export function initOrUpdateIndex(indexType: IndexType, indexData: IndexData, ta
initOrUpdateProperty(propertyMetadata, target, propertyKey)
}

function initOrUpdateGSI(indexes: Record<string, KeyType>, indexData: IndexData): Partial<PropertyMetadata<any>> {
function initOrUpdateGSI(indexes: Record<string, DynamoDB.KeyType>, indexData: IndexData): Partial<PropertyMetadata<any>> {
if (indexes[indexData.name]) {
// TODO LOW:INVESTIGATE when we throw an error we have a problem where multiple different classes extend one base class, this will be executed by multiple times
// throw new Error(
Expand Down
4 changes: 2 additions & 2 deletions src/decorator/impl/model/model.decorator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { KeyType } from 'aws-sdk/clients/dynamodb'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { kebabCase } from 'lodash'
import { ModelMetadata } from '../../metadata'
import { PropertyMetadata } from '../../metadata/property-metadata.model'
Expand Down Expand Up @@ -57,7 +57,7 @@ export function Model(opts: ModelData = {}): ClassDecorator {

function testForGSI<T>(
property: PropertyMetadata<T>,
): property is PropertyMetadata<T> & { keyForGSI: Record<string, KeyType> } {
): property is PropertyMetadata<T> & { keyForGSI: Record<string, DynamoDB.KeyType> } {
return !!(property.keyForGSI && Object.keys(property.keyForGSI).length)
}

Expand Down
6 changes: 3 additions & 3 deletions src/decorator/metadata/property-metadata.model.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { MapperForType } from '../../mapper/for-type/base.mapper'

// def good
import { KeyType } from 'aws-sdk/clients/dynamodb'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { Attribute } from '../../mapper/type/attribute.type'
import { ModelConstructor } from '../../model/model-constructor'

Expand All @@ -13,7 +13,7 @@ export interface TypeInfo {
}

export interface Key {
type: KeyType
type: DynamoDB.KeyType
uuid?: boolean
}

Expand Down Expand Up @@ -41,7 +41,7 @@ export interface PropertyMetadata<T, R extends Attribute = Attribute> {
mapper?: () => MapperForType<any, R>

// maps the index name to the key type to describe for which GSI this property describes a key attribute
keyForGSI?: Record<string, KeyType>
keyForGSI?: Record<string, DynamoDB.KeyType>

// holds all the the index names for which this property describes the sort key attribute
sortKeyForLSI?: string[]
Expand Down
6 changes: 3 additions & 3 deletions src/dynamo/batchget/batch-get-full.response.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// tslint:disable-next-line:interface-over-type-literal
import { BatchGetRequestMap, ConsumedCapacityMultiple } from 'aws-sdk/clients/dynamodb'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { BatchGetResponse } from './batch-get.response'

export interface BatchGetFullResponse {
Expand All @@ -10,9 +10,9 @@ export interface BatchGetFullResponse {
/**
* A map of tables and their respective keys that were not processed with the current response. The UnprocessedKeys value is in the same form as RequestItems, so the value can be provided directly to a subsequent BatchGetItem operation. For more information, see RequestItems in the Request Parameters section. Each element consists of: Keys - An array of primary key attribute values that define specific items in the table. ProjectionExpression - One or more attributes to be retrieved from the table or index. By default, all attributes are returned. If a requested attribute is not found, it does not appear in the result. ConsistentRead - The consistency of a read operation. If set to true, then a strongly consistent read is used; otherwise, an eventually consistent read is used. If there are no unprocessed keys remaining, the response contains an empty UnprocessedKeys map.
*/
UnprocessedKeys?: BatchGetRequestMap
UnprocessedKeys?: DynamoDB.BatchGetRequestMap
/**
* The read capacity units consumed by the entire BatchGetItem operation. Each element consists of: TableName - The table that consumed the provisioned throughput. CapacityUnits - The total number of capacity units consumed.
*/
ConsumedCapacity?: ConsumedCapacityMultiple
ConsumedCapacity?: DynamoDB.ConsumedCapacityMultiple
}
53 changes: 14 additions & 39 deletions src/dynamo/batchget/batch-get-utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
import { DynamoDB } from 'aws-sdk'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { of } from 'rxjs'
import { DynamoRx } from '../dynamo-rx'
import { batchGetItemsFetchAll, combineBatchGetResponses, hasUnprocessedKeys } from './batch-get-utils'

describe('batch-get utils', () => {

describe('hasUnprocessedKeys', () => {
it('should return bool according to given object', () => {
expect(hasUnprocessedKeys({})).toBeFalsy()
expect(hasUnprocessedKeys({ Responses: {} })).toBeFalsy()
expect(hasUnprocessedKeys({ UnprocessedKeys: {} })).toBeFalsy()
expect(hasUnprocessedKeys({ UnprocessedKeys: { 'aTableName': { Keys: [] } } })).toBeFalsy()
expect(hasUnprocessedKeys({ UnprocessedKeys: { 'aTableName': { Keys: [{ id: { S: 'id' } }] } } })).toBeTruthy()
expect(hasUnprocessedKeys({ UnprocessedKeys: { aTableName: { Keys: [] } } })).toBeFalsy()
expect(hasUnprocessedKeys({ UnprocessedKeys: { aTableName: { Keys: [{ id: { S: 'id' } }] } } })).toBeTruthy()
})
})

describe('combineBatchGetResponses', () => {
const resp1: DynamoDB.BatchGetItemOutput = {
Responses: {
'tableA': [
{ id: { S: 'id-a1' } },
],
'tableB': [
{ id: { S: 'id-b' } },
],
tableA: [{ id: { S: 'id-a1' } }],
tableB: [{ id: { S: 'id-b' } }],
},
UnprocessedKeys: {
'tableA:': { Keys: [{ id: { S: 'id-a2' } }] },
Expand All @@ -33,29 +28,18 @@ describe('batch-get utils', () => {
}
const resp2: DynamoDB.BatchGetItemOutput = {
Responses: {
'tableA': [
{ id: { S: 'id-a2' } },
],
'tableC': [
{ id: { S: 'id-c' } },
],
tableA: [{ id: { S: 'id-a2' } }],
tableC: [{ id: { S: 'id-c' } }],
},
UnprocessedKeys: {
'tableD:': { Keys: [{ id: { S: 'id-d' } }] },
},
}
const expectedOutput: DynamoDB.BatchGetItemOutput = {
Responses: {
'tableA': [
{ id: { S: 'id-a1' } },
{ id: { S: 'id-a2' } },
],
'tableB': [
{ id: { S: 'id-b' } },
],
'tableC': [
{ id: { S: 'id-c' } },
],
tableA: [{ id: { S: 'id-a1' } }, { id: { S: 'id-a2' } }],
tableB: [{ id: { S: 'id-b' } }],
tableC: [{ id: { S: 'id-c' } }],
},
UnprocessedKeys: {
'tableD:': { Keys: [{ id: { S: 'id-d' } }] },
Expand All @@ -64,7 +48,6 @@ describe('batch-get utils', () => {
it('should combine correctly', () => {
expect(combineBatchGetResponses(resp1)(resp2)).toEqual(expectedOutput)
})

})

describe('batchGetItemsFetchAll', () => {
Expand All @@ -74,17 +57,17 @@ describe('batch-get utils', () => {

const output1: DynamoDB.BatchGetItemOutput = {
Responses: {
'tableA': [{ id: { S: 'id-A' } }],
tableA: [{ id: { S: 'id-A' } }],
},
UnprocessedKeys: {
'tableA': {
tableA: {
Keys: [{ id: { S: 'id-A' } }],
},
},
}
const output2: DynamoDB.BatchGetItemOutput = {
Responses: {
'tableA': [{ id: { S: 'id-A' } }],
tableA: [{ id: { S: 'id-A' } }],
},
}

Expand All @@ -93,15 +76,9 @@ describe('batch-get utils', () => {
dynamoRx = <any>{ batchGetItems: batchGetItemsSpy }
backoffTimerMock = { next: jasmine.createSpy().and.returnValue({ value: 0 }) }

await batchGetItemsFetchAll(
dynamoRx,
<any>{},
<IterableIterator<number>><any>backoffTimerMock,
0,
).toPromise()
await batchGetItemsFetchAll(dynamoRx, <any>{}, <IterableIterator<number>>(<any>backoffTimerMock), 0).toPromise()
})


it('should use UnprocessedKeys for next request', () => {
expect(batchGetItemsSpy).toHaveBeenCalledTimes(2)
expect(batchGetItemsSpy.calls.mostRecent().args[0]).toBeDefined()
Expand All @@ -112,7 +89,5 @@ describe('batch-get utils', () => {
it('should backoff when UnprocessedItems', () => {
expect(backoffTimerMock.next).toHaveBeenCalledTimes(1)
})

})

})
5 changes: 2 additions & 3 deletions src/dynamo/batchget/batch-get-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { DynamoDB } from 'aws-sdk'
import { BatchGetRequestMap } from 'aws-sdk/clients/dynamodb'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { Observable, of } from 'rxjs'
import { delay, map, mergeMap } from 'rxjs/operators'
import { DynamoRx } from '../dynamo-rx'
Expand Down Expand Up @@ -44,7 +43,7 @@ export function batchGetItemsFetchAll(

export type BatchGetItemOutputWithUnprocessedKeys =
DynamoDB.BatchGetItemOutput
& { UnprocessedKeys: BatchGetRequestMap }
& { UnprocessedKeys: DynamoDB.BatchGetRequestMap }

export function hasUnprocessedKeys(response: DynamoDB.BatchGetItemOutput): response is BatchGetItemOutputWithUnprocessedKeys {
if (!response.UnprocessedKeys) {
Expand Down
2 changes: 1 addition & 1 deletion src/dynamo/batchget/batch-get.request.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DynamoDB } from 'aws-sdk'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { Observable } from 'rxjs'
import { map } from 'rxjs/operators'
import { metadataForClass } from '../../decorator/metadata/metadata-helper'
Expand Down
2 changes: 1 addition & 1 deletion src/dynamo/batchwrite/batch-write-utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DynamoDB } from 'aws-sdk'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { of } from 'rxjs'
import { DynamoRx } from '../dynamo-rx'
import { batchWriteItemsWriteAll, hasUnprocessedItems } from './batch-write-utils'
Expand Down
2 changes: 1 addition & 1 deletion src/dynamo/batchwrite/batch-write.request.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DynamoDB } from 'aws-sdk'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { Observable } from 'rxjs'
import { map } from 'rxjs/operators'
import { randomExponentialBackoffTimer } from '../../helper'
Expand Down
2 changes: 1 addition & 1 deletion src/dynamo/dynamo-rx.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// tslint:disable:no-empty
// tslint:disable:no-unnecessary-callback-wrapper

import { Config, Credentials } from 'aws-sdk'
import { Config, Credentials } from 'aws-sdk/global'
import { of } from 'rxjs'
import { resetDynamoEasyConfig } from '../../test/helper/resetDynamoEasyConfig.function'
import { updateDynamoEasyConfig } from '../config'
Expand Down
2 changes: 1 addition & 1 deletion src/dynamo/dynamo-rx.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Config } from 'aws-sdk'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { Config } from 'aws-sdk/global'
import { from, Observable } from 'rxjs'
import { switchMap } from 'rxjs/operators'
import { dynamoEasyConfig } from '../config/dynamo-easy-config'
Expand Down
8 changes: 4 additions & 4 deletions src/dynamo/expression/param-util.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { ExpressionAttributeNameMap, ExpressionAttributeValueMap, UpdateItemInput } from 'aws-sdk/clients/dynamodb'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { isEmpty, isString } from 'lodash'
import { ConditionalParams } from '../operation-params.type'
import { resolveAttributeValueNameConflicts } from './functions/resolve-attribute-value-name-conflicts.function'
import { Expression } from './type'
import { UpdateActionKeyword } from './type/update-action-keyword.type'

export function addUpdateExpression(updateExpression: Expression, params: UpdateItemInput): void {
export function addUpdateExpression(updateExpression: Expression, params: DynamoDB.UpdateItemInput): void {
addExpression('UpdateExpression', updateExpression, params)
}

Expand All @@ -16,12 +16,12 @@ export function addExpression(
) {
const nameSafeCondition = resolveAttributeValueNameConflicts(condition, params)

const expressionAttributeNames = <ExpressionAttributeNameMap>{
const expressionAttributeNames = <DynamoDB.ExpressionAttributeNameMap>{
...params.ExpressionAttributeNames,
...nameSafeCondition.attributeNames,
}

const expressionAttributeValues = <ExpressionAttributeValueMap>{
const expressionAttributeValues = <DynamoDB.ExpressionAttributeValueMap>{
...params.ExpressionAttributeValues,
...nameSafeCondition.attributeValues,
}
Expand Down
4 changes: 2 additions & 2 deletions src/dynamo/expression/request-expression-builder.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { QueryInput, QueryOutput } from 'aws-sdk/clients/dynamodb'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { Observable, of } from 'rxjs'
import { Organization } from '../../../test/models'
import { DynamoRx } from '../dynamo-rx'
import { QueryRequest } from '../request'
import { addCondition, addPartitionKeyCondition, addSortKeyCondition } from './request-expression-builder'

const DYNAMO_RX_MOCK: DynamoRx = <DynamoRx>{
query(params: QueryInput): Observable<QueryOutput> {
query(params: DynamoDB.QueryInput): Observable<DynamoDB.QueryOutput> {
return of({})
},
}
Expand Down
18 changes: 3 additions & 15 deletions src/dynamo/request/base.request.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
import {
BatchGetItemInput,
BatchWriteItemInput,
DeleteItemInput,
GetItemInput,
PutItemInput,
QueryInput,
ReturnConsumedCapacity,
ScanInput,
TransactGetItemsInput,
TransactWriteItemsInput,
UpdateItemInput,
} from 'aws-sdk/clients/dynamodb'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { metadataForClass } from '../../decorator/metadata'
import { Metadata } from '../../decorator/metadata/metadata'
import { ModelConstructor } from '../../model/model-constructor'
Expand All @@ -23,7 +11,7 @@ import { getTableName } from '../get-table-name.function'
* (even if the actual operation would allow to use multiple tables. e.g. BatchWriteSingleTable)
*/
export abstract class BaseRequest<T,
I extends DeleteItemInput | GetItemInput | PutItemInput | UpdateItemInput | QueryInput | ScanInput | BatchGetItemInput | BatchWriteItemInput | TransactGetItemsInput | TransactWriteItemsInput,
I extends DynamoDB.DeleteItemInput | DynamoDB.GetItemInput | DynamoDB.PutItemInput | DynamoDB.UpdateItemInput | DynamoDB.QueryInput | DynamoDB.ScanInput | DynamoDB.BatchGetItemInput |DynamoDB.BatchWriteItemInput | DynamoDB.TransactGetItemsInput | DynamoDB.TransactWriteItemsInput,
R extends BaseRequest<T, I, any>> {
readonly dynamoRx: DynamoRx
readonly modelClazz: ModelConstructor<T>
Expand All @@ -50,7 +38,7 @@ export abstract class BaseRequest<T,
this.params = <I>{}
}

returnConsumedCapacity(level: ReturnConsumedCapacity): R {
returnConsumedCapacity(level: DynamoDB.ReturnConsumedCapacity): R {
this.params.ReturnConsumedCapacity = level
return <R><any>this
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DynamoDB } from 'aws-sdk'
import * as DynamoDB from 'aws-sdk/clients/dynamodb'
import { of } from 'rxjs'
// tslint:disable:no-unnecessary-class
// tslint:disable:no-unused-expression
Expand Down
Loading