@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 CHANGED
@@ -2,12 +2,12 @@ Library for Forge KVS.
2
2
 
3
3
  Usage example:
4
4
  ```typescript
5
- import kvs, { Conditions, Sort, Filter } from "@forge/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', Conditions.beginsWith('example'))
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(Conditions.greaterThan(30))
34
- .filters(new Filter<Employee>().and('employmentyear', Conditions.equalTo(2025)))
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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=transaction-api.test.d.ts.map
@@ -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
+ });
@@ -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 FilterBuilder<T> implements Filter<T> {
10
- and(field: keyof T, condition: EntityFilterClauses): AndFilter<T>;
11
- or(field: keyof T, condition: EntityFilterClauses): OrFilter<T>;
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,EAEN,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;AAgED,qBAAa,aAAa,CAAC,CAAC,CAAE,YAAW,MAAM,CAAC,CAAC,CAAC;IAChD,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,mBAAmB,GAAG,SAAS,CAAC,CAAC,CAAC;IAIjE,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,mBAAmB,GAAG,QAAQ,CAAC,CAAC,CAAC;CAGhE"}
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"}
@@ -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.items;
34
- if (filter instanceof AndFilterBuilder) {
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
- class FilterBuilder {
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":"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"}
1
+ {"version":3,"file":"kvs-api.d.ts","sourceRoot":"","sources":["../../src/interfaces/kvs-api.ts"],"names":[],"mappings":"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"}
@@ -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;AAEvC,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;CAC7C;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"}
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"}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
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;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,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;CAG5C"}
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;
@@ -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
@@ -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,EAEX,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;YAQxD,OAAO;CAyBtB"}
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"}
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=transaction-request-builder.test.d.ts.map
@@ -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.2-next.2",
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": {