@forge/kvs 0.0.2-next.2 → 0.1.0-next.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -4
- package/out/__test__/index.test.js +14 -0
- package/out/__test__/transaction-api.test.d.ts +2 -0
- package/out/__test__/transaction-api.test.d.ts.map +1 -0
- package/out/__test__/transaction-api.test.js +130 -0
- package/out/entity-query.d.ts +17 -4
- package/out/entity-query.d.ts.map +1 -1
- package/out/entity-query.js +11 -9
- package/out/interfaces/kvs-api.d.ts +28 -5
- package/out/interfaces/kvs-api.d.ts.map +1 -1
- package/out/interfaces/kvs.d.ts +2 -0
- package/out/interfaces/kvs.d.ts.map +1 -1
- package/out/interfaces/transaction.d.ts +29 -0
- package/out/interfaces/transaction.d.ts.map +1 -0
- package/out/interfaces/transaction.js +2 -0
- package/out/kvs.d.ts +2 -0
- package/out/kvs.d.ts.map +1 -1
- package/out/kvs.js +4 -0
- package/out/storage-api.d.ts +2 -1
- package/out/storage-api.d.ts.map +1 -1
- package/out/storage-api.js +3 -0
- package/out/transaction-api.d.ts +14 -0
- package/out/transaction-api.d.ts.map +1 -0
- package/out/transaction-api.js +66 -0
- package/out/utils/__test__/transaction-request-builder.test.d.ts +2 -0
- package/out/utils/__test__/transaction-request-builder.test.d.ts.map +1 -0
- package/out/utils/__test__/transaction-request-builder.test.js +117 -0
- package/out/utils/transaction-request-builder.d.ts +6 -0
- package/out/utils/transaction-request-builder.d.ts.map +1 -0
- package/out/utils/transaction-request-builder.js +49 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -2,12 +2,12 @@ Library for Forge KVS.
|
|
|
2
2
|
|
|
3
3
|
Usage example:
|
|
4
4
|
```typescript
|
|
5
|
-
import kvs, {
|
|
5
|
+
import kvs, { FilterConditons, WhereConditions, Sort, Filter } from "@forge/kvs";
|
|
6
6
|
|
|
7
7
|
await kvs.set<string>('example-key', 'bar');
|
|
8
8
|
await kvs.get<string>('example-key');
|
|
9
9
|
await kvs.delete('example-key');
|
|
10
|
-
await kvs.query().where('key',
|
|
10
|
+
await kvs.query().where('key', WhereConditions.beginsWith('example'))
|
|
11
11
|
|
|
12
12
|
type Employee = {
|
|
13
13
|
surname: string;
|
|
@@ -30,12 +30,29 @@ await kvs
|
|
|
30
30
|
.entity<Employee>('employee')
|
|
31
31
|
.query()
|
|
32
32
|
.index('by-age')
|
|
33
|
-
.where(
|
|
34
|
-
.filters(new Filter<Employee>().and('employmentyear',
|
|
33
|
+
.where(WhereConditions.greaterThan(30))
|
|
34
|
+
.filters(new Filter<Employee>().and('employmentyear', FilterConditions.equalTo(2025)))
|
|
35
35
|
.sort(Sort.DESC)
|
|
36
36
|
.getMany()
|
|
37
37
|
|
|
38
38
|
await kvs.setSecret('example-key', 'Hello world');
|
|
39
39
|
await kvs.getSecret('example-key');
|
|
40
40
|
await kvs.deleteSecret('example-key');
|
|
41
|
+
|
|
42
|
+
const conditions = new Filter<Employee>().and('lastName', FilterConditions.beginsWith('S'))
|
|
43
|
+
.and('firstName', FilterConditions.beginsWith('blah'));
|
|
44
|
+
|
|
45
|
+
await kvs
|
|
46
|
+
.transact()
|
|
47
|
+
.set('key', 'value')
|
|
48
|
+
.set('entityKey', 'value', {
|
|
49
|
+
entityName: 'author',
|
|
50
|
+
conditions: new Filter<Employee>().and('lastName', FilterConditions.beginsWith('S'))
|
|
51
|
+
.and('firstName', FilterConditions.beginsWith('blah'))
|
|
52
|
+
})
|
|
53
|
+
.delete('some-key')
|
|
54
|
+
.delete('another-key', { entityName: 'employee', conditions })
|
|
55
|
+
.check('third-key', conditions)
|
|
56
|
+
.check('fourth-key', conditions, { entityName: 'author' })
|
|
57
|
+
.execute();
|
|
41
58
|
```
|
|
@@ -506,4 +506,18 @@ describe('KVS', () => {
|
|
|
506
506
|
})
|
|
507
507
|
}));
|
|
508
508
|
});
|
|
509
|
+
it('should sumbit transaction correctly', async () => {
|
|
510
|
+
const response = new Response(undefined, {
|
|
511
|
+
status: 200,
|
|
512
|
+
headers: { 'x-trace-id': traceId }
|
|
513
|
+
});
|
|
514
|
+
const { sut, apiClient } = prepare(response);
|
|
515
|
+
await sut.transact().set('foo', 'bar').delete('bar').execute();
|
|
516
|
+
expect(apiClient).toHaveBeenCalledWith('/api/v1/transaction', expect.objectContaining({
|
|
517
|
+
body: JSON.stringify({
|
|
518
|
+
set: [{ key: 'foo', value: 'bar' }],
|
|
519
|
+
delete: [{ key: 'bar' }]
|
|
520
|
+
})
|
|
521
|
+
}));
|
|
522
|
+
});
|
|
509
523
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-api.test.d.ts","sourceRoot":"","sources":["../../src/__test__/transaction-api.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const transaction_api_1 = require("../transaction-api");
|
|
5
|
+
const storage_api_1 = require("../storage-api");
|
|
6
|
+
const xen_test_util_1 = require("@atlassian/xen-test-util");
|
|
7
|
+
const entity_query_1 = require("../entity-query");
|
|
8
|
+
const TransactionUtils = tslib_1.__importStar(require("../utils/transaction-request-builder"));
|
|
9
|
+
const key = 'key';
|
|
10
|
+
const entityName = 'entity';
|
|
11
|
+
const defaultEntity = { field1: 'test' };
|
|
12
|
+
jest.mock('../utils/transaction-request-builder');
|
|
13
|
+
class TestTransactionBuilderImpl extends transaction_api_1.TransactionBuilderImpl {
|
|
14
|
+
getSets() {
|
|
15
|
+
return this.sets;
|
|
16
|
+
}
|
|
17
|
+
getDeletes() {
|
|
18
|
+
return this.deletes;
|
|
19
|
+
}
|
|
20
|
+
getChecks() {
|
|
21
|
+
return this.checks;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
describe('TransactionBuilderImpl', () => {
|
|
25
|
+
function setupForTests(sets = [], deletes = [], checks = []) {
|
|
26
|
+
const storageApi = (0, xen_test_util_1.mock)(storage_api_1.StorageApi);
|
|
27
|
+
const transactionBuilder = new TestTransactionBuilderImpl(storageApi, sets, deletes, checks);
|
|
28
|
+
return { storageApi, transactionBuilder };
|
|
29
|
+
}
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
jest.clearAllMocks();
|
|
32
|
+
});
|
|
33
|
+
describe('set', () => {
|
|
34
|
+
it.each(['test', 100, false, [1, 2, 3], { key: 'value' }])('set should add into array of transaction set with value %s', (value) => {
|
|
35
|
+
const { transactionBuilder } = setupForTests();
|
|
36
|
+
transactionBuilder.set(key, value);
|
|
37
|
+
expect(transactionBuilder.getSets()).toContainEqual({ key, value });
|
|
38
|
+
expect(transactionBuilder.getDeletes()).toHaveLength(0);
|
|
39
|
+
expect(transactionBuilder.getChecks()).toHaveLength(0);
|
|
40
|
+
});
|
|
41
|
+
it('set should add into array of transaction set with entity and condition', () => {
|
|
42
|
+
const { transactionBuilder } = setupForTests();
|
|
43
|
+
const filterBuilder = new entity_query_1.FilterBuilder();
|
|
44
|
+
transactionBuilder.set(key, defaultEntity, { entityName, conditions: filterBuilder });
|
|
45
|
+
expect(transactionBuilder.getSets()).toContainEqual({
|
|
46
|
+
key,
|
|
47
|
+
value: defaultEntity,
|
|
48
|
+
entity: { entityName, conditions: filterBuilder }
|
|
49
|
+
});
|
|
50
|
+
expect(transactionBuilder.getDeletes()).toHaveLength(0);
|
|
51
|
+
expect(transactionBuilder.getChecks()).toHaveLength(0);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('delete', () => {
|
|
55
|
+
it('delete should add into array of transaction delete', () => {
|
|
56
|
+
const { transactionBuilder } = setupForTests();
|
|
57
|
+
transactionBuilder.delete(key);
|
|
58
|
+
expect(transactionBuilder.getDeletes()).toContainEqual({ key });
|
|
59
|
+
expect(transactionBuilder.getSets()).toHaveLength(0);
|
|
60
|
+
expect(transactionBuilder.getChecks()).toHaveLength(0);
|
|
61
|
+
});
|
|
62
|
+
it('delete should add into array of transaction delete with entity and condition', () => {
|
|
63
|
+
const { transactionBuilder } = setupForTests();
|
|
64
|
+
const filterBuilder = new entity_query_1.FilterBuilder();
|
|
65
|
+
transactionBuilder.delete(key, { entityName, conditions: filterBuilder });
|
|
66
|
+
expect(transactionBuilder.getDeletes()).toContainEqual({
|
|
67
|
+
key,
|
|
68
|
+
entity: { entityName, conditions: filterBuilder }
|
|
69
|
+
});
|
|
70
|
+
expect(transactionBuilder.getSets()).toHaveLength(0);
|
|
71
|
+
expect(transactionBuilder.getChecks()).toHaveLength(0);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('check', () => {
|
|
75
|
+
it('check should add into array of transaction check with entity and condition', () => {
|
|
76
|
+
const { transactionBuilder } = setupForTests();
|
|
77
|
+
const filterBuilder = new entity_query_1.FilterBuilder();
|
|
78
|
+
transactionBuilder.check(key, { entityName, conditions: filterBuilder });
|
|
79
|
+
expect(transactionBuilder.getChecks()).toContainEqual({
|
|
80
|
+
key,
|
|
81
|
+
entity: { entityName, conditions: filterBuilder }
|
|
82
|
+
});
|
|
83
|
+
expect(transactionBuilder.getSets()).toHaveLength(0);
|
|
84
|
+
expect(transactionBuilder.getDeletes()).toHaveLength(0);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
describe('execute', () => {
|
|
88
|
+
it('should map items to request state before sending to storage api', async () => {
|
|
89
|
+
const transactSet = [{ key, value: 'test' }];
|
|
90
|
+
const requestSet = { key, value: 'test' };
|
|
91
|
+
const transactDelete = [{ key }];
|
|
92
|
+
const requestDelete = { key };
|
|
93
|
+
const transactCheck = [
|
|
94
|
+
{ key, entity: { entityName, conditions: new entity_query_1.FilterBuilder() } }
|
|
95
|
+
];
|
|
96
|
+
const requestCheck = { key, entityName, conditions: { and: [] } };
|
|
97
|
+
const { storageApi, transactionBuilder } = setupForTests(transactSet, transactDelete, transactCheck);
|
|
98
|
+
const buildSetSpy = jest.spyOn(TransactionUtils, 'buildRequestSet');
|
|
99
|
+
buildSetSpy.mockReturnValueOnce(requestSet);
|
|
100
|
+
const buildDeleteSpy = jest.spyOn(TransactionUtils, 'buildRequestDeletes');
|
|
101
|
+
buildDeleteSpy.mockReturnValueOnce(requestDelete);
|
|
102
|
+
const buildCheckSpy = jest.spyOn(TransactionUtils, 'buildRequestChecks');
|
|
103
|
+
buildCheckSpy.mockReturnValueOnce(requestCheck);
|
|
104
|
+
await transactionBuilder.execute();
|
|
105
|
+
expect(buildSetSpy).toHaveBeenCalledWith(transactSet[0], 0, transactSet);
|
|
106
|
+
expect(buildDeleteSpy).toHaveBeenCalledWith(transactDelete[0], 0, transactDelete);
|
|
107
|
+
expect(buildCheckSpy).toHaveBeenCalledWith(transactCheck[0], 0, transactCheck);
|
|
108
|
+
expect(storageApi.transact).toHaveBeenCalledWith({
|
|
109
|
+
set: [requestSet],
|
|
110
|
+
delete: [requestDelete],
|
|
111
|
+
check: [requestCheck]
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
it('should set undefined if no items are present', async () => {
|
|
115
|
+
const { storageApi, transactionBuilder } = setupForTests();
|
|
116
|
+
const buildSetSpy = jest.spyOn(TransactionUtils, 'buildRequestSet');
|
|
117
|
+
const buildDeleteSpy = jest.spyOn(TransactionUtils, 'buildRequestDeletes');
|
|
118
|
+
const buildCheckSpy = jest.spyOn(TransactionUtils, 'buildRequestChecks');
|
|
119
|
+
await transactionBuilder.execute();
|
|
120
|
+
expect(buildSetSpy).not.toHaveBeenCalled();
|
|
121
|
+
expect(buildDeleteSpy).not.toHaveBeenCalled();
|
|
122
|
+
expect(buildCheckSpy).not.toHaveBeenCalled();
|
|
123
|
+
expect(storageApi.transact).toHaveBeenCalledWith({
|
|
124
|
+
set: undefined,
|
|
125
|
+
delete: undefined,
|
|
126
|
+
check: undefined
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
package/out/entity-query.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EntityFilterClauses, AndFilter, EntityQueryBuilder, IndexQueryBuilder, Filter, IndexOptions, OrFilter } from './interfaces/entity-query';
|
|
1
|
+
import { EntityFilterClauses, AndFilter, EntityQueryBuilder, IndexQueryBuilder, Filter, FilterItem, IndexOptions, OrFilter } from './interfaces/entity-query';
|
|
2
2
|
import { StorageApi } from './storage-api';
|
|
3
3
|
export declare class KvsIndexQueryBuilder<T> implements IndexQueryBuilder<T> {
|
|
4
4
|
private readonly entityName;
|
|
@@ -6,8 +6,21 @@ export declare class KvsIndexQueryBuilder<T> implements IndexQueryBuilder<T> {
|
|
|
6
6
|
constructor(entityName: string, storageApi: StorageApi);
|
|
7
7
|
index(name: string, indexOptions?: IndexOptions<T>): EntityQueryBuilder<T>;
|
|
8
8
|
}
|
|
9
|
-
export declare class
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
export declare abstract class BaseFilter<T> {
|
|
10
|
+
protected readonly items: Array<FilterItem<T>>;
|
|
11
|
+
constructor(items?: Array<FilterItem<T>>);
|
|
12
|
+
filters(): Array<FilterItem<T>>;
|
|
13
|
+
operator(): "or" | "and";
|
|
12
14
|
}
|
|
15
|
+
export declare class FilterBuilder<T> extends BaseFilter<T> implements Filter<T> {
|
|
16
|
+
and(field: keyof T, condition: EntityFilterClauses): AndFilterBuilder<T>;
|
|
17
|
+
or(field: keyof T, condition: EntityFilterClauses): OrFilterBuilder<T>;
|
|
18
|
+
}
|
|
19
|
+
declare class AndFilterBuilder<T> extends BaseFilter<T> implements AndFilter<T> {
|
|
20
|
+
and(field: keyof T, condition: EntityFilterClauses): this;
|
|
21
|
+
}
|
|
22
|
+
declare class OrFilterBuilder<T> extends BaseFilter<T> implements OrFilter<T> {
|
|
23
|
+
or(field: keyof T, condition: EntityFilterClauses): this;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
13
26
|
//# sourceMappingURL=entity-query.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-query.d.ts","sourceRoot":"","sources":["../src/entity-query.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAGnB,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,MAAM,
|
|
1
|
+
{"version":3,"file":"entity-query.d.ts","sourceRoot":"","sources":["../src/entity-query.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAGnB,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,MAAM,EACN,UAAU,EACV,YAAY,EACZ,QAAQ,EACT,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,qBAAa,oBAAoB,CAAC,CAAC,CAAE,YAAW,iBAAiB,CAAC,CAAC,CAAC;IAEhE,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBADV,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,UAAU;IAGzC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC;CAQ3E;AAwDD,8BAAsB,UAAU,CAAC,CAAC;IACpB,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAA3B,KAAK,GAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAM;IAExD,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAI/B,QAAQ;CAGhB;AAED,qBAAa,aAAa,CAAC,CAAC,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAE,YAAW,MAAM,CAAC,CAAC,CAAC;IACtE,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,mBAAmB,GAAG,gBAAgB,CAAC,CAAC,CAAC;IAIxE,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,mBAAmB,GAAG,eAAe,CAAC,CAAC,CAAC;CAGvE;AAED,cAAM,gBAAgB,CAAC,CAAC,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAE,YAAW,SAAS,CAAC,CAAC,CAAC;IACrE,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,mBAAmB,GAAG,IAAI;CAI1D;AAED,cAAM,eAAe,CAAC,CAAC,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAE,YAAW,QAAQ,CAAC,CAAC,CAAC;IACnE,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,mBAAmB,GAAG,IAAI;CAIzD"}
|
package/out/entity-query.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FilterBuilder = exports.KvsIndexQueryBuilder = void 0;
|
|
3
|
+
exports.FilterBuilder = exports.BaseFilter = exports.KvsIndexQueryBuilder = void 0;
|
|
4
4
|
class KvsIndexQueryBuilder {
|
|
5
5
|
entityName;
|
|
6
6
|
storageApi;
|
|
@@ -30,13 +30,8 @@ class KvsEntityQueryBuilder {
|
|
|
30
30
|
return this;
|
|
31
31
|
}
|
|
32
32
|
filters(filter) {
|
|
33
|
-
this.queryOptions.filters = filter.
|
|
34
|
-
|
|
35
|
-
this.queryOptions.filterOperator = 'and';
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
this.queryOptions.filterOperator = 'or';
|
|
39
|
-
}
|
|
33
|
+
this.queryOptions.filters = filter.filters();
|
|
34
|
+
this.queryOptions.filterOperator = filter.operator();
|
|
40
35
|
return this;
|
|
41
36
|
}
|
|
42
37
|
sort(sort) {
|
|
@@ -76,8 +71,15 @@ class BaseFilter {
|
|
|
76
71
|
constructor(items = []) {
|
|
77
72
|
this.items = items;
|
|
78
73
|
}
|
|
74
|
+
filters() {
|
|
75
|
+
return this.items;
|
|
76
|
+
}
|
|
77
|
+
operator() {
|
|
78
|
+
return this instanceof AndFilterBuilder ? 'and' : 'or';
|
|
79
|
+
}
|
|
79
80
|
}
|
|
80
|
-
|
|
81
|
+
exports.BaseFilter = BaseFilter;
|
|
82
|
+
class FilterBuilder extends BaseFilter {
|
|
81
83
|
and(field, condition) {
|
|
82
84
|
return new AndFilterBuilder().and(field, condition);
|
|
83
85
|
}
|
|
@@ -43,11 +43,15 @@ export declare type EntitySetRequest<T> = EntityKeyValueSchema<T>;
|
|
|
43
43
|
export declare type EntitySetResponse = void;
|
|
44
44
|
export declare type EntityDeleteRequest = EntityKeySchema;
|
|
45
45
|
export declare type EntityDeleteResponse = void;
|
|
46
|
-
declare type EntityQueryFilter = {
|
|
46
|
+
export declare type EntityQueryFilter = {
|
|
47
47
|
condition: 'BEGINS_WITH' | 'BETWEEN' | 'CONTAINS' | 'EQUAL_TO' | 'EXISTS' | 'GREATER_THAN' | 'GREATER_THAN_EQUAL_TO' | 'LESS_THAN' | 'LESS_THAN_EQUAL_TO' | 'NOT_CONTAINS' | 'NOT_EQUAL_TO' | 'NOT_EXISTS';
|
|
48
48
|
property: string;
|
|
49
49
|
values: Array<unknown>;
|
|
50
50
|
};
|
|
51
|
+
export declare type EntityQueryFilters = {
|
|
52
|
+
or?: Array<EntityQueryFilter>;
|
|
53
|
+
and?: Array<EntityQueryFilter>;
|
|
54
|
+
};
|
|
51
55
|
export declare type EntityQueryRequest = {
|
|
52
56
|
limit?: number;
|
|
53
57
|
cursor?: string;
|
|
@@ -55,10 +59,7 @@ export declare type EntityQueryRequest = {
|
|
|
55
59
|
condition: 'BEGINS_WITH' | 'BETWEEN' | 'EQUAL_TO' | 'GREATER_THAN' | 'GREATER_THAN_EQUAL_TO' | 'LESS_THAN' | 'LESS_THAN_EQUAL_TO';
|
|
56
60
|
values: Array<unknown>;
|
|
57
61
|
};
|
|
58
|
-
filters?:
|
|
59
|
-
or?: Array<EntityQueryFilter>;
|
|
60
|
-
and?: Array<EntityQueryFilter>;
|
|
61
|
-
};
|
|
62
|
+
filters?: EntityQueryFilters;
|
|
62
63
|
sort?: 'ASC' | 'DESC';
|
|
63
64
|
partition?: Array<unknown>;
|
|
64
65
|
entityName: string;
|
|
@@ -68,5 +69,27 @@ export declare type EntityQueryResponse<T> = {
|
|
|
68
69
|
data: Array<KeyValueSchema<T>>;
|
|
69
70
|
cursor?: string;
|
|
70
71
|
};
|
|
72
|
+
export declare type TransactionCondition = EntityQueryFilters;
|
|
73
|
+
export declare type RequestSet<T> = {
|
|
74
|
+
key: string;
|
|
75
|
+
value: T;
|
|
76
|
+
entityName?: string;
|
|
77
|
+
conditions?: TransactionCondition;
|
|
78
|
+
};
|
|
79
|
+
export declare type RequestDelete = {
|
|
80
|
+
key: string;
|
|
81
|
+
entityName?: string;
|
|
82
|
+
conditions?: TransactionCondition;
|
|
83
|
+
};
|
|
84
|
+
export declare type RequestCheck = {
|
|
85
|
+
key: string;
|
|
86
|
+
entityName?: string;
|
|
87
|
+
conditions: TransactionCondition;
|
|
88
|
+
};
|
|
89
|
+
export declare type TransactionRequest<T> = {
|
|
90
|
+
set?: RequestSet<T>[];
|
|
91
|
+
delete?: RequestDelete[];
|
|
92
|
+
check?: RequestCheck[];
|
|
93
|
+
};
|
|
71
94
|
export {};
|
|
72
95
|
//# sourceMappingURL=kvs-api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kvs-api.d.ts","sourceRoot":"","sources":["../../src/interfaces/kvs-api.ts"],"names":[],"mappings":"AAAA,aAAK,SAAS,GAAG;IACf,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,aAAK,cAAc,CAAC,CAAC,IAAI,SAAS,GAAG;IACnC,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAEF,oBAAY,UAAU,GAAG,SAAS,CAAC;AACnC,oBAAY,WAAW,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;AAE/C,oBAAY,UAAU,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;AAC9C,oBAAY,WAAW,GAAG,IAAI,CAAC;AAE/B,oBAAY,aAAa,GAAG,SAAS,CAAC;AACtC,oBAAY,cAAc,GAAG,IAAI,CAAC;AAElC,aAAK,UAAU,GAAG;IAChB,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,KAAK,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;CACxB,CAAC;AACF,oBAAY,YAAY,GAAG;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;CAC3B,CAAC;AACF,oBAAY,aAAa,CAAC,CAAC,IAAI;IAC7B,IAAI,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAGF,oBAAY,gBAAgB,GAAG,SAAS,CAAC;AACzC,oBAAY,iBAAiB,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;AAErD,oBAAY,gBAAgB,CAAC,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC;AACpD,oBAAY,iBAAiB,GAAG,IAAI,CAAC;AAErC,oBAAY,mBAAmB,GAAG,SAAS,CAAC;AAC5C,oBAAY,oBAAoB,GAAG,IAAI,CAAC;AAGxC,aAAK,eAAe,GAAG;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,aAAK,oBAAoB,CAAC,CAAC,IAAI,eAAe,GAAG;IAC/C,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAEF,oBAAY,gBAAgB,GAAG,eAAe,CAAC;AAC/C,oBAAY,iBAAiB,CAAC,CAAC,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAE3D,oBAAY,gBAAgB,CAAC,CAAC,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAC1D,oBAAY,iBAAiB,GAAG,IAAI,CAAC;AAErC,oBAAY,mBAAmB,GAAG,eAAe,CAAC;AAClD,oBAAY,oBAAoB,GAAG,IAAI,CAAC;AAExC,
|
|
1
|
+
{"version":3,"file":"kvs-api.d.ts","sourceRoot":"","sources":["../../src/interfaces/kvs-api.ts"],"names":[],"mappings":"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"}
|
package/out/interfaces/kvs.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { IndexQueryBuilder } from './entity-query';
|
|
2
2
|
import { QueryBuilder } from './query';
|
|
3
|
+
import { TransactionBuilder } from './transaction';
|
|
3
4
|
export interface Kvs {
|
|
4
5
|
get<T>(key: string): Promise<T>;
|
|
5
6
|
set<T>(key: string, value: T): Promise<void>;
|
|
@@ -9,6 +10,7 @@ export interface Kvs {
|
|
|
9
10
|
setSecret<T>(key: string, value: T): Promise<void>;
|
|
10
11
|
deleteSecret(key: string): Promise<void>;
|
|
11
12
|
entity<T>(entityName: string): KvsEntity<T>;
|
|
13
|
+
transact(): TransactionBuilder;
|
|
12
14
|
}
|
|
13
15
|
export interface KvsEntity<T> {
|
|
14
16
|
get(key: string): Promise<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kvs.d.ts","sourceRoot":"","sources":["../../src/interfaces/kvs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"kvs.d.ts","sourceRoot":"","sources":["../../src/interfaces/kvs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,WAAW,GAAG;IAClB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAChC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,KAAK,IAAI,YAAY,CAAC;IAEtB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACtC,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzC,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;IAE5C,QAAQ,IAAI,kBAAkB,CAAC;CAChC;AAED,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,KAAK,IAAI,iBAAiB,CAAC,CAAC,CAAC,CAAC;CAC/B"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { BaseFilter } from '../entity-query';
|
|
2
|
+
export interface TransactSet<T> {
|
|
3
|
+
key: string;
|
|
4
|
+
value: T;
|
|
5
|
+
entity?: EntityConditions<T>;
|
|
6
|
+
}
|
|
7
|
+
export interface TransactDelete<T> {
|
|
8
|
+
key: string;
|
|
9
|
+
entity?: EntityConditions<T>;
|
|
10
|
+
}
|
|
11
|
+
export interface TransactCheck<T> {
|
|
12
|
+
key: string;
|
|
13
|
+
entity: EntityRequiredConditions<T>;
|
|
14
|
+
}
|
|
15
|
+
export declare type EntityConditions<T> = {
|
|
16
|
+
entityName: string;
|
|
17
|
+
conditions?: BaseFilter<T>;
|
|
18
|
+
};
|
|
19
|
+
export declare type EntityRequiredConditions<T> = Omit<EntityConditions<T>, 'conditions'> & {
|
|
20
|
+
conditions: BaseFilter<T>;
|
|
21
|
+
};
|
|
22
|
+
export declare type StorageValue = string | number | boolean | Record<string, any> | any[];
|
|
23
|
+
export interface TransactionBuilder {
|
|
24
|
+
set<T>(key: string, value: T, entity?: EntityConditions<T>): this;
|
|
25
|
+
delete<T>(key: string, entity?: EntityConditions<T>): this;
|
|
26
|
+
check<T>(key: string, entity: EntityRequiredConditions<T>): this;
|
|
27
|
+
execute(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=transaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/interfaces/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAK7C,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,CAAC,CAAC;IACT,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAC9B;AAKD,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAC9B;AAKD,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC,CAAC;CACrC;AAKD,oBAAY,gBAAgB,CAAC,CAAC,IAAI;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CAC5B,CAAC;AAKF,oBAAY,wBAAwB,CAAC,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,GAAG;IAClF,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;CAC3B,CAAC;AAKF,oBAAY,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC;AAMnF,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAClE,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC3D,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACjE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
|
package/out/kvs.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { KvsEntity, Kvs } from './interfaces/kvs';
|
|
2
2
|
import { QueryBuilder } from './interfaces/query';
|
|
3
|
+
import { TransactionBuilder } from './interfaces/transaction';
|
|
3
4
|
import { StorageApi } from './storage-api';
|
|
4
5
|
export declare class KvsImpl implements Kvs {
|
|
5
6
|
private readonly storageApi;
|
|
@@ -12,5 +13,6 @@ export declare class KvsImpl implements Kvs {
|
|
|
12
13
|
setSecret<T>(key: string, value: T): Promise<void>;
|
|
13
14
|
deleteSecret(key: string): Promise<void>;
|
|
14
15
|
entity<T>(entityName: string): KvsEntity<T>;
|
|
16
|
+
transact(): TransactionBuilder;
|
|
15
17
|
}
|
|
16
18
|
//# sourceMappingURL=kvs.d.ts.map
|
package/out/kvs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kvs.d.ts","sourceRoot":"","sources":["../src/kvs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"kvs.d.ts","sourceRoot":"","sources":["../src/kvs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,qBAAa,OAAQ,YAAW,GAAG;IACrB,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,UAAU;IAEnD,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAI/B,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,KAAK,IAAI,YAAY;IAIrB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;IAIrC,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,MAAM,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAI3C,QAAQ,IAAI,kBAAkB;CAG/B"}
|
package/out/kvs.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.KvsImpl = void 0;
|
|
4
4
|
const entity_1 = require("./entity");
|
|
5
5
|
const query_1 = require("./query");
|
|
6
|
+
const transaction_api_1 = require("./transaction-api");
|
|
6
7
|
class KvsImpl {
|
|
7
8
|
storageApi;
|
|
8
9
|
constructor(storageApi) {
|
|
@@ -32,5 +33,8 @@ class KvsImpl {
|
|
|
32
33
|
entity(entityName) {
|
|
33
34
|
return new entity_1.EntityImpl(entityName, this.storageApi);
|
|
34
35
|
}
|
|
36
|
+
transact() {
|
|
37
|
+
return new transaction_api_1.TransactionBuilderImpl(this.storageApi);
|
|
38
|
+
}
|
|
35
39
|
}
|
|
36
40
|
exports.KvsImpl = KvsImpl;
|
package/out/storage-api.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FetchMethod } from '@forge/api';
|
|
2
2
|
import { ListResult } from './interfaces/types';
|
|
3
|
-
import { DeleteRequest, EntityDeleteRequest, EntityGetRequest, EntityQueryRequest, EntitySetRequest, GetRequest, QueryRequest, SecretDeleteRequest, SecretGetRequest, SecretSetRequest, SetRequest } from './interfaces/kvs-api';
|
|
3
|
+
import { DeleteRequest, EntityDeleteRequest, EntityGetRequest, EntityQueryRequest, EntitySetRequest, GetRequest, QueryRequest, SecretDeleteRequest, SecretGetRequest, SecretSetRequest, SetRequest, TransactionRequest } from './interfaces/kvs-api';
|
|
4
4
|
export declare class StorageApi {
|
|
5
5
|
private apiClient;
|
|
6
6
|
constructor(apiClient: FetchMethod);
|
|
@@ -15,6 +15,7 @@ export declare class StorageApi {
|
|
|
15
15
|
deleteEntity(body: EntityDeleteRequest): Promise<void>;
|
|
16
16
|
query<T>(body: QueryRequest): Promise<ListResult<T>>;
|
|
17
17
|
queryEntity<T>(body: EntityQueryRequest): Promise<ListResult<T>>;
|
|
18
|
+
transact<T>(transactionRequest: TransactionRequest<T>): Promise<void>;
|
|
18
19
|
private request;
|
|
19
20
|
}
|
|
20
21
|
//# sourceMappingURL=storage-api.d.ts.map
|
package/out/storage-api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-api.d.ts","sourceRoot":"","sources":["../src/storage-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EACL,aAAa,EAEb,mBAAmB,EAEnB,gBAAgB,EAEhB,kBAAkB,EAElB,gBAAgB,EAEhB,UAAU,EAEV,YAAY,EAEZ,mBAAmB,EAEnB,gBAAgB,EAEhB,gBAAgB,EAEhB,UAAU,
|
|
1
|
+
{"version":3,"file":"storage-api.d.ts","sourceRoot":"","sources":["../src/storage-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EACL,aAAa,EAEb,mBAAmB,EAEnB,gBAAgB,EAEhB,kBAAkB,EAElB,gBAAgB,EAEhB,UAAU,EAEV,YAAY,EAEZ,mBAAmB,EAEnB,gBAAgB,EAEhB,gBAAgB,EAEhB,UAAU,EAEV,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAE9B,qBAAa,UAAU;IACT,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,WAAW;IAEpC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC;IAKpC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,CAAC,CAAC;IAKhD,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,CAAC,CAAC;IAKhD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAQpD,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAQhE,QAAQ,CAAC,CAAC,EAAE,kBAAkB,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAI7D,OAAO;CAyBtB"}
|
package/out/storage-api.js
CHANGED
|
@@ -52,6 +52,9 @@ class StorageApi {
|
|
|
52
52
|
nextCursor: rs.cursor
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
|
+
async transact(transactionRequest) {
|
|
56
|
+
await this.request('/api/v1/transaction', transactionRequest, false);
|
|
57
|
+
}
|
|
55
58
|
async request(path, body, isResponseExpected) {
|
|
56
59
|
const requestBody = {
|
|
57
60
|
method: 'POST',
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StorageApi } from './storage-api';
|
|
2
|
+
import { EntityConditions, EntityRequiredConditions, TransactCheck, TransactDelete, TransactionBuilder, TransactSet } from './interfaces/transaction';
|
|
3
|
+
export declare class TransactionBuilderImpl implements TransactionBuilder {
|
|
4
|
+
private readonly storageApi;
|
|
5
|
+
protected sets: TransactSet<unknown>[];
|
|
6
|
+
protected deletes: TransactDelete<unknown>[];
|
|
7
|
+
protected checks: TransactCheck<unknown>[];
|
|
8
|
+
constructor(storageApi: StorageApi, sets?: TransactSet<unknown>[], deletes?: TransactDelete<unknown>[], checks?: TransactCheck<unknown>[]);
|
|
9
|
+
set<T>(key: string, value: T, entity?: EntityConditions<T>): this;
|
|
10
|
+
delete<T>(key: string, entity?: EntityConditions<T>): this;
|
|
11
|
+
check<T>(key: string, { entityName, conditions }: EntityRequiredConditions<T>): this;
|
|
12
|
+
execute(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=transaction-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-api.d.ts","sourceRoot":"","sources":["../src/transaction-api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EACL,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAIlC,qBAAa,sBAAuB,YAAW,kBAAkB;IAE7D,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE;IACtC,SAAS,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE;IAC5C,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE;gBAHzB,UAAU,EAAE,UAAU,EAC7B,IAAI,GAAE,WAAW,CAAC,OAAO,CAAC,EAAO,EACjC,OAAO,GAAE,cAAc,CAAC,OAAO,CAAC,EAAO,EACvC,MAAM,GAAE,aAAa,CAAC,OAAO,CAAC,EAAO;IAGjD,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI;IAkBjE,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI;IAiB1D,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,IAAI;IAa9E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAY/B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TransactionBuilderImpl = void 0;
|
|
4
|
+
const transaction_request_builder_1 = require("./utils/transaction-request-builder");
|
|
5
|
+
class TransactionBuilderImpl {
|
|
6
|
+
storageApi;
|
|
7
|
+
sets;
|
|
8
|
+
deletes;
|
|
9
|
+
checks;
|
|
10
|
+
constructor(storageApi, sets = [], deletes = [], checks = []) {
|
|
11
|
+
this.storageApi = storageApi;
|
|
12
|
+
this.sets = sets;
|
|
13
|
+
this.deletes = deletes;
|
|
14
|
+
this.checks = checks;
|
|
15
|
+
}
|
|
16
|
+
set(key, value, entity) {
|
|
17
|
+
const transactSet = {
|
|
18
|
+
key,
|
|
19
|
+
value
|
|
20
|
+
};
|
|
21
|
+
if (entity) {
|
|
22
|
+
transactSet.entity = {
|
|
23
|
+
entityName: entity.entityName,
|
|
24
|
+
conditions: entity.conditions
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
this.sets.push(transactSet);
|
|
28
|
+
return this;
|
|
29
|
+
}
|
|
30
|
+
delete(key, entity) {
|
|
31
|
+
const transactDelete = {
|
|
32
|
+
key
|
|
33
|
+
};
|
|
34
|
+
if (entity) {
|
|
35
|
+
transactDelete.entity = {
|
|
36
|
+
entityName: entity.entityName,
|
|
37
|
+
conditions: entity.conditions
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
this.deletes.push(transactDelete);
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
check(key, { entityName, conditions }) {
|
|
44
|
+
const transactCheck = {
|
|
45
|
+
key,
|
|
46
|
+
entity: {
|
|
47
|
+
entityName,
|
|
48
|
+
conditions
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
this.checks.push(transactCheck);
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
async execute() {
|
|
55
|
+
const undefineEmptyArray = (arr) => {
|
|
56
|
+
return arr.length === 0 ? undefined : arr;
|
|
57
|
+
};
|
|
58
|
+
const request = {
|
|
59
|
+
set: undefineEmptyArray(this.sets.map(transaction_request_builder_1.buildRequestSet)),
|
|
60
|
+
delete: undefineEmptyArray(this.deletes.map(transaction_request_builder_1.buildRequestDeletes)),
|
|
61
|
+
check: undefineEmptyArray(this.checks.map(transaction_request_builder_1.buildRequestChecks))
|
|
62
|
+
};
|
|
63
|
+
await this.storageApi.transact(request);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.TransactionBuilderImpl = TransactionBuilderImpl;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-request-builder.test.d.ts","sourceRoot":"","sources":["../../../src/utils/__test__/transaction-request-builder.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const transaction_request_builder_1 = require("../transaction-request-builder");
|
|
4
|
+
const entity_query_1 = require("../../entity-query");
|
|
5
|
+
const conditions_1 = require("../../conditions");
|
|
6
|
+
const errors_1 = require("../../errors");
|
|
7
|
+
const key = 'key';
|
|
8
|
+
const entityName = 'testEntity';
|
|
9
|
+
describe('transaction-request-builder', () => {
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
jest.clearAllMocks();
|
|
12
|
+
});
|
|
13
|
+
describe('buildRequestSet', () => {
|
|
14
|
+
it('should build request set without entity', () => {
|
|
15
|
+
const value = 'value';
|
|
16
|
+
const transactSet = {
|
|
17
|
+
key,
|
|
18
|
+
value
|
|
19
|
+
};
|
|
20
|
+
const result = (0, transaction_request_builder_1.buildRequestSet)(transactSet);
|
|
21
|
+
expect(result).toEqual({ key, value });
|
|
22
|
+
});
|
|
23
|
+
it('should build request set with entity and conditions', () => {
|
|
24
|
+
const conditions = new entity_query_1.FilterBuilder().and('field1', conditions_1.FilterConditions.beginsWith('S'));
|
|
25
|
+
const transactSet = {
|
|
26
|
+
key,
|
|
27
|
+
value: { field1: 'test' },
|
|
28
|
+
entity: {
|
|
29
|
+
entityName,
|
|
30
|
+
conditions
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const result = (0, transaction_request_builder_1.buildRequestSet)(transactSet);
|
|
34
|
+
expect(result).toEqual({
|
|
35
|
+
key,
|
|
36
|
+
value: { field1: 'test' },
|
|
37
|
+
entityName,
|
|
38
|
+
conditions: { and: conditions.filters() }
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
it('should throw error if no conditions are set', () => {
|
|
42
|
+
const conditions = new entity_query_1.FilterBuilder();
|
|
43
|
+
const transactSet = {
|
|
44
|
+
key,
|
|
45
|
+
value: { field1: 'test' },
|
|
46
|
+
entity: {
|
|
47
|
+
entityName,
|
|
48
|
+
conditions
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
expect(() => (0, transaction_request_builder_1.buildRequestSet)(transactSet)).toMatchError(new errors_1.ForgeKvsError('Builder must have at least one condition set'));
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('buildRequestDelete', () => {
|
|
55
|
+
it('should build request delete without entity', () => {
|
|
56
|
+
const transactDelete = { key };
|
|
57
|
+
const result = (0, transaction_request_builder_1.buildRequestDeletes)(transactDelete);
|
|
58
|
+
expect(result).toEqual({ key });
|
|
59
|
+
});
|
|
60
|
+
it('should build request delete with entity and conditions', () => {
|
|
61
|
+
const conditions = new entity_query_1.FilterBuilder().and('field1', conditions_1.FilterConditions.beginsWith('S'));
|
|
62
|
+
const transactDelete = {
|
|
63
|
+
key,
|
|
64
|
+
entity: {
|
|
65
|
+
entityName,
|
|
66
|
+
conditions
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const result = (0, transaction_request_builder_1.buildRequestDeletes)(transactDelete);
|
|
70
|
+
expect(result).toEqual({
|
|
71
|
+
key,
|
|
72
|
+
entityName,
|
|
73
|
+
conditions: { and: conditions.filters() }
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
it('should throw error if no conditions are set', () => {
|
|
77
|
+
const conditions = new entity_query_1.FilterBuilder();
|
|
78
|
+
const transactDelete = {
|
|
79
|
+
key,
|
|
80
|
+
entity: {
|
|
81
|
+
entityName,
|
|
82
|
+
conditions
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
expect(() => (0, transaction_request_builder_1.buildRequestDeletes)(transactDelete)).toMatchError(new errors_1.ForgeKvsError('Builder must have at least one condition set'));
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
describe('buildRequestCheck', () => {
|
|
89
|
+
it('should build request check with entity and conditions', () => {
|
|
90
|
+
const conditions = new entity_query_1.FilterBuilder().and('field1', conditions_1.FilterConditions.beginsWith('S'));
|
|
91
|
+
const transactCheck = {
|
|
92
|
+
key,
|
|
93
|
+
entity: {
|
|
94
|
+
entityName,
|
|
95
|
+
conditions
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const result = (0, transaction_request_builder_1.buildRequestChecks)(transactCheck);
|
|
99
|
+
expect(result).toEqual({
|
|
100
|
+
key,
|
|
101
|
+
entityName,
|
|
102
|
+
conditions: { and: conditions.filters() }
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
it('should throw error if no conditions are set', () => {
|
|
106
|
+
const conditions = new entity_query_1.FilterBuilder();
|
|
107
|
+
const transactCheck = {
|
|
108
|
+
key,
|
|
109
|
+
entity: {
|
|
110
|
+
entityName,
|
|
111
|
+
conditions
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
expect(() => (0, transaction_request_builder_1.buildRequestChecks)(transactCheck)).toMatchError(new errors_1.ForgeKvsError('Builder must have at least one condition set'));
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { RequestCheck, RequestDelete, RequestSet } from '../interfaces/kvs-api';
|
|
2
|
+
import { TransactCheck, TransactDelete, TransactSet } from '../interfaces/transaction';
|
|
3
|
+
export declare const buildRequestSet: <T>(setOperation: TransactSet<T>) => RequestSet<T>;
|
|
4
|
+
export declare const buildRequestDeletes: <T>(deleteOperation: TransactDelete<T>) => RequestDelete;
|
|
5
|
+
export declare const buildRequestChecks: <T>(checkOperation: TransactCheck<T>) => RequestCheck;
|
|
6
|
+
//# sourceMappingURL=transaction-request-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction-request-builder.d.ts","sourceRoot":"","sources":["../../src/utils/transaction-request-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACpG,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAoBvF,eAAO,MAAM,eAAe,oDAW3B,CAAC;AAEF,eAAO,MAAM,mBAAmB,6CAA4C,aAU3E,CAAC;AAEF,eAAO,MAAM,kBAAkB,2CAA0C,YAUxE,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildRequestChecks = exports.buildRequestDeletes = exports.buildRequestSet = void 0;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
5
|
+
function buildConditionsRequest(filter) {
|
|
6
|
+
if (!filter) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
if (filter.filters().length === 0) {
|
|
10
|
+
throw new errors_1.ForgeKvsError('Builder must have at least one condition set');
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
[filter.operator()]: filter.filters()
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const buildRequestSet = (setOperation) => {
|
|
17
|
+
const { key, value, entity } = setOperation;
|
|
18
|
+
const entityName = entity?.entityName;
|
|
19
|
+
const conditions = buildConditionsRequest(entity?.conditions);
|
|
20
|
+
return {
|
|
21
|
+
key,
|
|
22
|
+
value,
|
|
23
|
+
entityName,
|
|
24
|
+
conditions
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
exports.buildRequestSet = buildRequestSet;
|
|
28
|
+
const buildRequestDeletes = (deleteOperation) => {
|
|
29
|
+
const { key, entity } = deleteOperation;
|
|
30
|
+
const entityName = entity?.entityName;
|
|
31
|
+
const conditions = buildConditionsRequest(entity?.conditions);
|
|
32
|
+
return {
|
|
33
|
+
key,
|
|
34
|
+
entityName,
|
|
35
|
+
conditions
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
exports.buildRequestDeletes = buildRequestDeletes;
|
|
39
|
+
const buildRequestChecks = (checkOperation) => {
|
|
40
|
+
const { key, entity } = checkOperation;
|
|
41
|
+
const entityName = entity.entityName;
|
|
42
|
+
const conditions = buildConditionsRequest(entity.conditions);
|
|
43
|
+
return {
|
|
44
|
+
key,
|
|
45
|
+
entityName,
|
|
46
|
+
conditions
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
exports.buildRequestChecks = buildRequestChecks;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forge/kvs",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0-next.3",
|
|
4
4
|
"description": "Forge Key Value Store SDK",
|
|
5
5
|
"author": "Atlassian",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"compile": "tsc -b -v"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
+
"@atlassian/xen-test-util": "^4.2.0",
|
|
18
19
|
"@types/node": "14.18.63"
|
|
19
20
|
},
|
|
20
21
|
"dependencies": {
|