diff --git a/src/batchGet.ts b/src/batchGet.ts index 25ea2f6..d08c05f 100644 --- a/src/batchGet.ts +++ b/src/batchGet.ts @@ -49,7 +49,7 @@ export class BatchGet extends ReadOperate implements AsyncIt } async then( - onfulfilled?: (value?: M[]) => TRes | PromiseLike, + onfulfilled: (value?: M[]) => TRes | PromiseLike = (r => r) as any, onrejected?: (reason: any) => TRes | PromiseLike, ) { try { @@ -57,9 +57,13 @@ export class BatchGet extends ReadOperate implements AsyncIt for await (let m of this) { result.push(m) } - onfulfilled(result) + return onfulfilled(result) } catch (err) { - onrejected(err) + if (onrejected) { + onrejected(err) + } else { + throw err + } } } diff --git a/src/batchWrite.ts b/src/batchWrite.ts index 2f816fa..cc270cd 100644 --- a/src/batchWrite.ts +++ b/src/batchWrite.ts @@ -63,7 +63,7 @@ export class BatchWrite extends WriteOperate implements Asyn } async then( - onfulfilled?: (value?: number) => TRes | PromiseLike, + onfulfilled: (value?: number) => TRes | PromiseLike = (r => r) as any, onrejected?: (reason: any) => TRes | PromiseLike, ) { try { @@ -72,9 +72,13 @@ export class BatchWrite extends WriteOperate implements Asyn for await (let m of this) { time++ } - onfulfilled(time) + return onfulfilled(time) } catch (err) { - onrejected(err) + if (onrejected) { + onrejected(err) + } else { + throw err + } } } diff --git a/src/database.ts b/src/database.ts index 4c33693..2b21a93 100644 --- a/src/database.ts +++ b/src/database.ts @@ -43,7 +43,9 @@ export class Database extends Schema { // return this._documentClient // || (this._documentClient = new DocumentClient()) // } - static client = new DocumentClient() + static client = new DocumentClient({ + convertEmptyValues: true + }) /** * Configure tiamo to use a DynamoDB local endpoint for testing. diff --git a/src/delete.ts b/src/delete.ts index 8530fd3..f98e5aa 100644 --- a/src/delete.ts +++ b/src/delete.ts @@ -23,7 +23,7 @@ export class Delete extends ConditionWriteOperate { } then( - onfulfilled?: (value?: M) => TRes | PromiseLike, + onfulfilled: (value?: M) => TRes | PromiseLike = (r => r) as any, onrejected?: (reason: any) => TRes | PromiseLike, ) { const params = this.toJSON() diff --git a/src/get.ts b/src/get.ts index 744a8e9..ec12091 100644 --- a/src/get.ts +++ b/src/get.ts @@ -28,7 +28,7 @@ export class Get extends ReadOperate { } then( - onfulfilled?: (value?: M) => TRes | PromiseLike, + onfulfilled: (value?: M) => TRes | PromiseLike = (r => r) as any, onrejected?: (reason: any) => TRes | PromiseLike, ) { const { Model } = this.options diff --git a/src/model.ts b/src/model.ts index 3f79c93..08a5fc3 100644 --- a/src/model.ts +++ b/src/model.ts @@ -184,12 +184,12 @@ export class Model extends Database { this.pre('save', this.validate.bind(this)) } - get isNew() { + isNew() { return !!Reflect.getOwnMetadata('tiamo:cache:new', this) } - set isNew(value: boolean) { - Reflect.defineMetadata('tiamo:cache:new', value, this) - } + // set isNew(value: boolean) { + // Reflect.defineMetadata('tiamo:cache:new', value, this) + // } /** * Hook instance diff --git a/src/put.ts b/src/put.ts index 5813008..53af8ea 100644 --- a/src/put.ts +++ b/src/put.ts @@ -23,7 +23,7 @@ export class Put extends ConditionWriteOperate { } then( - onfulfilled?: (value?: M) => TRes | PromiseLike, + onfulfilled: (value?: M) => TRes | PromiseLike = (r => r) as any, onrejected?: (reason: any) => TRes | PromiseLike, ) { const params = this.toJSON() diff --git a/src/query.ts b/src/query.ts index d40c8e1..6fa2dee 100644 --- a/src/query.ts +++ b/src/query.ts @@ -91,7 +91,7 @@ export class Query extends MultiReadOperate< } async then( - onfulfilled?: (value?: R) => TRes | PromiseLike, + onfulfilled: (value?: R) => TRes | PromiseLike = (r => r) as any, onrejected?: (reason: any) => TRes | PromiseLike, ) { try { @@ -105,7 +105,7 @@ export class Query extends MultiReadOperate< } result.push(res) } - onfulfilled(this.options.one ? first : result) + return onfulfilled(this.options.one ? first : result) } catch (err) { onrejected(err) } diff --git a/src/scan.ts b/src/scan.ts index 17f5f9d..fd7d643 100644 --- a/src/scan.ts +++ b/src/scan.ts @@ -41,7 +41,7 @@ export class Scan extends MultiReadOperate implements AsyncI } async then( - onfulfilled?: (value?: M[]) => TRes | PromiseLike, + onfulfilled: (value?: M[]) => TRes | PromiseLike = (r => r) as any, onrejected?: (reason: any) => TRes | PromiseLike, ) { try { @@ -49,7 +49,8 @@ export class Scan extends MultiReadOperate implements AsyncI for await (let res of this) { result.push(res) } - onfulfilled(result) + + return onfulfilled(result) } catch (err) { onrejected(err) } diff --git a/src/update.ts b/src/update.ts index 047a64a..b921fe7 100644 --- a/src/update.ts +++ b/src/update.ts @@ -1,7 +1,7 @@ import { DynamoDB } from 'aws-sdk' import { DocumentClient } from 'aws-sdk/clients/dynamodb' import { Model, $update } from './model' -import { expression, ExpressionLogic } from './expression' +import { expression } from './expression' import { ConditionWriteOperate, OperateOptions } from './operate' export class Update extends ConditionWriteOperate { @@ -28,6 +28,11 @@ export class Update extends ConditionWriteOperate { set(key: string) { const { options } = this const f = (op: string, op2?: string) => (val?: V) => { + if (op === '=' && (val as any) === '') { + // return this.remove(key) + val = null + } + const { exprs, names, values } = expression(key)(op, op2)(val) exprs.forEach(e => options.setExprs.add(e)) Object.assign(options.names, names) @@ -86,7 +91,7 @@ export class Update extends ConditionWriteOperate { } then( - onfulfilled?: (value?: M) => TRes | PromiseLike, + onfulfilled: (value?: M) => TRes | PromiseLike = (r => r) as any, onrejected?: (reason: any) => TRes | PromiseLike, ) { const params = this.toJSON() diff --git a/test/model.test.ts b/test/model.test.ts index 6039935..5f84029 100644 --- a/test/model.test.ts +++ b/test/model.test.ts @@ -20,12 +20,12 @@ describe('Model', () => { it('default is new', () => { let foo1 = new Foo() - expect(foo1.isNew).toBe(true) + expect(foo1.isNew()).toBe(true) let foo2 = new Foo({}, { isNew: false }) - expect(foo2.isNew).toBe(false) - expect(foo1.isNew).toBe(true) + expect(foo2.isNew()).toBe(false) + expect(foo1.isNew()).toBe(true) }) }) @@ -53,9 +53,9 @@ describe('Model', () => { expect(value.unknown).toBeUndefined() }) - it('validate before create', async () => { - await expect(Foo.create({ id: 42 as any })).rejects.toThrow('"id" must be a string') - }) + // it('validate before create', async () => { + // await expect(Foo.create({ id: 42 as any })).rejects.toThrow('"id" must be a string') + // }) it('validate before create', async () => { await expect(new Foo({ id: 42 as any }).save()).rejects.toThrow('"id" must be a string') @@ -325,6 +325,10 @@ describe('Model', () => { expect(e.name).toBeUndefined() expect(e.arr[0]).toBe('1') }) + + it('allow call then() without arguments', async () => { + await expect(GetExample.get({ id: '1' }).then().then()).resolves.toBeDefined() + }) }) describe('query', () => { @@ -462,6 +466,14 @@ describe('Model', () => { expect(m.id).toBe('1') }) + + it('throw if query without cond', async () => { + await expect(Example.query()).rejects.toThrow('Either the KeyConditions or KeyConditionExpression parameter must be specified in the request.') + }) + + it('allow call then() without arguments', async () => { + await expect(Example.query().where('id').eq('1').then().then()).resolves.toBeDefined() + }) }) describe('scan', () => { @@ -531,6 +543,10 @@ describe('Model', () => { expect(c).toBe(2) }) + + it('allow call then() without arguments', async () => { + await expect(ScanExample.scan().then().then()).resolves.toBeDefined() + }) }) describe('update', () => { @@ -752,6 +768,18 @@ describe('Model', () => { it('update id = 1 nothing', async () => { await expect(Example.update({ id: '1' })).rejects.toThrow('Update expression is empty') }) + + it('update id = 1 set name to empty string', async () => { + let u = Example.update({ id: '1' }) + .set('name').to('') + + expect(u.toJSON().ExpressionAttributeValues[':name']).toBeNull() + await expect(u.then()).resolves.not.toThrow() + }) + + it('allow call then() without arguments', async () => { + await expect(Example.update({id: '1'}).remove('name').then().then()).resolves.toBeDefined() + }) }) describe('delete', () => { @@ -870,6 +898,10 @@ describe('Model', () => { expect(a.length).toBe(0) }) + + it('allow call then() without arguments', async () => { + await expect(Example.delete({ id: '1' }).then().then()).resolves.toBeDefined() + }) }) describe('batch', () => { @@ -1069,6 +1101,14 @@ describe('Model', () => { await expect(p).resolves.toHaveLength(2) }) + + it('allow call then() without arguments', async () => { + await expect(BatchExample.batch().put([{ id: 1 }]).get([{ id: 1 }]).then().then()).resolves.toBeDefined() + }) + + it('throw if call catch() without arguments', async () => { + await expect(BatchExample.batch().get([]).catch().catch()).rejects.toThrow('Member must have length greater than or equal to 1') + }) }) xit('', async () => {