@forge/cache 1.0.3-next.0 → 1.0.3-next.0-experimental-ab129b0-experimental-f18cf39
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/out/cache.d.ts +6 -1
- package/out/cache.d.ts.map +1 -1
- package/out/cache.js +20 -0
- package/out/interfaces/cache.d.ts +4 -0
- package/out/interfaces/cache.d.ts.map +1 -1
- package/out/kvs/conditions.d.ts +38 -0
- package/out/kvs/conditions.d.ts.map +1 -0
- package/out/kvs/conditions.js +98 -0
- package/out/kvs/entity-query.d.ts +26 -0
- package/out/kvs/entity-query.d.ts.map +1 -0
- package/out/kvs/entity-query.js +102 -0
- package/out/kvs/entity.d.ts +13 -0
- package/out/kvs/entity.d.ts.map +1 -0
- package/out/kvs/entity.js +35 -0
- package/out/kvs/errors.d.ts +21 -0
- package/out/kvs/errors.d.ts.map +1 -0
- package/out/kvs/errors.js +26 -0
- package/out/kvs/index.d.ts +10 -0
- package/out/kvs/index.d.ts.map +1 -0
- package/out/kvs/index.js +42 -0
- package/out/kvs/interfaces/entity-query.d.ts +41 -0
- package/out/kvs/interfaces/entity-query.d.ts.map +1 -0
- package/out/kvs/interfaces/entity-query.js +2 -0
- package/out/kvs/interfaces/kvs-api.d.ts +95 -0
- package/out/kvs/interfaces/kvs-api.d.ts.map +1 -0
- package/out/kvs/interfaces/kvs-api.js +2 -0
- package/out/kvs/interfaces/kvs.d.ts +21 -0
- package/out/kvs/interfaces/kvs.d.ts.map +1 -0
- package/out/kvs/interfaces/kvs.js +2 -0
- package/out/kvs/interfaces/query.d.ts +17 -0
- package/out/kvs/interfaces/query.d.ts.map +1 -0
- package/out/kvs/interfaces/query.js +2 -0
- package/out/kvs/interfaces/transaction.d.ts +29 -0
- package/out/kvs/interfaces/transaction.d.ts.map +1 -0
- package/out/kvs/interfaces/transaction.js +2 -0
- package/out/kvs/interfaces/types.d.ts +64 -0
- package/out/kvs/interfaces/types.d.ts.map +1 -0
- package/out/kvs/interfaces/types.js +8 -0
- package/out/kvs/kvs.d.ts +18 -0
- package/out/kvs/kvs.d.ts.map +1 -0
- package/out/kvs/kvs.js +40 -0
- package/out/kvs/query.d.ts +14 -0
- package/out/kvs/query.d.ts.map +1 -0
- package/out/kvs/query.js +38 -0
- package/out/kvs/storage-api.d.ts +22 -0
- package/out/kvs/storage-api.d.ts.map +1 -0
- package/out/kvs/storage-api.js +103 -0
- package/out/kvs/transaction-api.d.ts +14 -0
- package/out/kvs/transaction-api.d.ts.map +1 -0
- package/out/kvs/transaction-api.js +66 -0
- package/out/kvs/utils/error-handling.d.ts +7 -0
- package/out/kvs/utils/error-handling.d.ts.map +1 -0
- package/out/kvs/utils/error-handling.js +42 -0
- package/out/kvs/utils/transaction-request-builder.d.ts +6 -0
- package/out/kvs/utils/transaction-request-builder.d.ts.map +1 -0
- package/out/kvs/utils/transaction-request-builder.js +49 -0
- package/out/tunnel.d.ts +4 -0
- package/out/tunnel.d.ts.map +1 -1
- package/out/tunnel.js +12 -0
- package/package.json +2 -2
- package/out/__test__/cache.test.d.ts +0 -2
- package/out/__test__/cache.test.d.ts.map +0 -1
- package/out/__test__/cache.test.js +0 -358
- package/out/__test__/tunnel.test.d.ts +0 -2
- package/out/__test__/tunnel.test.d.ts.map +0 -1
- package/out/__test__/tunnel.test.js +0 -176
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkResponseError = exports.extractTraceId = exports.safeGetParsedBody = exports.isForgeError = void 0;
|
|
4
|
+
const errors_1 = require("../errors");
|
|
5
|
+
function isForgeError(body) {
|
|
6
|
+
return typeof body === 'object' && body !== null && 'code' in body && 'message' in body;
|
|
7
|
+
}
|
|
8
|
+
exports.isForgeError = isForgeError;
|
|
9
|
+
function safeGetParsedBody(text) {
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(text);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.safeGetParsedBody = safeGetParsedBody;
|
|
18
|
+
function extractTraceId(response) {
|
|
19
|
+
return response.headers.get('x-b3-traceid') || response.headers.get('x-trace-id');
|
|
20
|
+
}
|
|
21
|
+
exports.extractTraceId = extractTraceId;
|
|
22
|
+
async function checkResponseError(response) {
|
|
23
|
+
if (response.ok) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const responseText = await response.text();
|
|
27
|
+
const details = {
|
|
28
|
+
status: response.status,
|
|
29
|
+
statusText: response.statusText,
|
|
30
|
+
traceId: extractTraceId(response)
|
|
31
|
+
};
|
|
32
|
+
const parsedBody = safeGetParsedBody(responseText);
|
|
33
|
+
if (parsedBody && isForgeError(parsedBody)) {
|
|
34
|
+
throw new errors_1.ForgeKvsAPIError(details, parsedBody);
|
|
35
|
+
}
|
|
36
|
+
throw new errors_1.ForgeKvsAPIError(details, {
|
|
37
|
+
code: 'UNKNOWN_ERROR',
|
|
38
|
+
message: 'Unexpected error in Forge KVS API',
|
|
39
|
+
context: { responseText }
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
exports.checkResponseError = checkResponseError;
|
|
@@ -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/kvs/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/out/tunnel.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ export declare class TunnelCache implements IForgeCache {
|
|
|
8
8
|
private __localStore;
|
|
9
9
|
private events;
|
|
10
10
|
constructor(fileName?: string);
|
|
11
|
+
setKvsDirect<T>(key: string, value: T): Promise<void>;
|
|
12
|
+
getKvsDirect<T>(key: string): Promise<T | undefined>;
|
|
13
|
+
setKvs<T>(key: string, value: T): Promise<void>;
|
|
14
|
+
getKvs<T>(key: string): Promise<T | undefined>;
|
|
11
15
|
private saveToFile;
|
|
12
16
|
private loadFromFile;
|
|
13
17
|
set(key: string, value: string, opt?: {
|
package/out/tunnel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAWjD,oBAAY,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAAC,CAAC;AAGzE,eAAO,MAAM,SAAS,WAAW,CAAC;AAClC,eAAO,MAAM,UAAU,QAA4B,CAAC;AAgBpD,qBAAa,WAAY,YAAW,WAAW;IAGjC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAFrC,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,MAAM,CAAe;gBACA,QAAQ,GAAE,MAAmB;IAS1D,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAGrD,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAIpD,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAG/C,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAK9C,OAAO,CAAC,UAAU;IAiBlB,OAAO,CAAC,YAAY;IAmBP,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IASxC,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAc9F,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAY3F,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAYpC,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAc3E,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmBrD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmB7C,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAaxC,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAgB3E,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAsBlG,OAAO,CAAC,oBAAoB;CAK7B"}
|
package/out/tunnel.js
CHANGED
|
@@ -30,6 +30,18 @@ class TunnelCache {
|
|
|
30
30
|
this.saveToFile();
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
|
+
setKvsDirect(key, value) {
|
|
34
|
+
throw new Error('Method not implemented.');
|
|
35
|
+
}
|
|
36
|
+
getKvsDirect(key) {
|
|
37
|
+
throw new Error('Method not implemented.');
|
|
38
|
+
}
|
|
39
|
+
setKvs(key, value) {
|
|
40
|
+
throw new Error('Method not implemented.');
|
|
41
|
+
}
|
|
42
|
+
getKvs(key) {
|
|
43
|
+
throw new Error('Method not implemented.');
|
|
44
|
+
}
|
|
33
45
|
saveToFile() {
|
|
34
46
|
const obj = {};
|
|
35
47
|
for (const [k, v] of this.__localStore) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forge/cache",
|
|
3
|
-
"version": "1.0.3-next.0",
|
|
3
|
+
"version": "1.0.3-next.0-experimental-ab129b0-experimental-f18cf39",
|
|
4
4
|
"description": "Forge Cache methods",
|
|
5
5
|
"author": "Atlassian",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"tmp": "^0.2.3"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@forge/api": "^6.0.3-next.0",
|
|
24
|
+
"@forge/api": "^6.0.3-next.0-experimental-ab129b0",
|
|
25
25
|
"agentkeepalive": "^4.5.0",
|
|
26
26
|
"node-fetch": "2.7.0",
|
|
27
27
|
"object-sizeof": "^2.6.5"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache.test.d.ts","sourceRoot":"","sources":["../../src/__test__/cache.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
5
|
-
const cache_1 = require("../cache");
|
|
6
|
-
jest.mock('node-fetch');
|
|
7
|
-
const fetchMock = node_fetch_1.default;
|
|
8
|
-
describe('Forge Cache', () => {
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
global['__forge_runtime__'] = {
|
|
11
|
-
proxy: {
|
|
12
|
-
token: 'token',
|
|
13
|
-
url: 'https://proxy.atlassian.com'
|
|
14
|
-
},
|
|
15
|
-
rms: {
|
|
16
|
-
url: 'https://dev.services.atlassian.com',
|
|
17
|
-
host: 'rockmelon-storage.dev.atl-paas.net'
|
|
18
|
-
},
|
|
19
|
-
tracing: {
|
|
20
|
-
traceId: 'trace-id-test',
|
|
21
|
-
spanId: 'span-id-test'
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
});
|
|
25
|
-
it('chooses the v2 fetch based on runtime', async () => {
|
|
26
|
-
const cacheClient = (0, cache_1.connect)();
|
|
27
|
-
await cacheClient['client']('asdf');
|
|
28
|
-
expect(fetchMock).toHaveBeenCalled();
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
describe('createFetch', () => {
|
|
32
|
-
it('fetch fails when rms config is not available', async () => {
|
|
33
|
-
global['__forge_runtime__'] = {
|
|
34
|
-
proxy: {
|
|
35
|
-
token: 'token',
|
|
36
|
-
url: 'https://proxy.atlassian.com'
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
await expect((0, cache_1.createFetchRmsRuntimeV2)()).rejects.toThrowError(new Error('RMS config not available.'));
|
|
40
|
-
});
|
|
41
|
-
it('creates a fetch that adds the right headers and url', async () => {
|
|
42
|
-
global['__forge_runtime__'] = {
|
|
43
|
-
proxy: {
|
|
44
|
-
token: 'token',
|
|
45
|
-
url: 'https://proxy.atlassian.com'
|
|
46
|
-
},
|
|
47
|
-
rms: {
|
|
48
|
-
url: 'https://dev.services.atlassian.com',
|
|
49
|
-
host: 'rockmelon-storage.dev.atl-paas.net'
|
|
50
|
-
},
|
|
51
|
-
tracing: {
|
|
52
|
-
traceId: 'trace-id-test',
|
|
53
|
-
spanId: 'span-id-test'
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
const fetch = (0, cache_1.createFetchRmsRuntimeV2)();
|
|
57
|
-
await fetch('path');
|
|
58
|
-
const [absoluteUrl, options] = fetchMock.mock.lastCall ?? ['', {}];
|
|
59
|
-
expect(absoluteUrl.toString()).toEqual('https://rms/path');
|
|
60
|
-
expect((options?.agent)['passthrough']['keepAlive']).toBeTruthy();
|
|
61
|
-
expect(options?.headers).toMatchObject({
|
|
62
|
-
Authorization: 'Bearer token',
|
|
63
|
-
Host: 'rockmelon-storage.dev.atl-paas.net',
|
|
64
|
-
'x-b3-traceid': 'trace-id-test',
|
|
65
|
-
'x-b3-spanid': 'span-id-test'
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
describe('Cache', () => {
|
|
70
|
-
function buildCache() {
|
|
71
|
-
const fetch = jest.fn();
|
|
72
|
-
const cache = new cache_1.Cache(fetch);
|
|
73
|
-
return { cache, fetch };
|
|
74
|
-
}
|
|
75
|
-
describe('set', () => {
|
|
76
|
-
it('handles success', async () => {
|
|
77
|
-
const { cache, fetch } = buildCache();
|
|
78
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({}), status: 200 });
|
|
79
|
-
await cache.set('key', 'value');
|
|
80
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
81
|
-
});
|
|
82
|
-
it('handles success with ttl', async () => {
|
|
83
|
-
const { cache, fetch } = buildCache();
|
|
84
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({}), status: 200 });
|
|
85
|
-
await cache.set('key', 'value', { ttlSeconds: 100 });
|
|
86
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
87
|
-
});
|
|
88
|
-
it('handles failure', async () => {
|
|
89
|
-
const { cache, fetch } = buildCache();
|
|
90
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
91
|
-
await expect(cache.set('key', 'value', { ttlSeconds: 100 })).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
92
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
93
|
-
});
|
|
94
|
-
it('handles failure with error code', async () => {
|
|
95
|
-
const { cache, fetch } = buildCache();
|
|
96
|
-
fetch.mockResolvedValueOnce({
|
|
97
|
-
ok: false,
|
|
98
|
-
text: async () => JSON.stringify({ error: { code: 'NOT_ALLOWED', title: 'Invalid operation' } }),
|
|
99
|
-
status: 400
|
|
100
|
-
});
|
|
101
|
-
await expect(cache.set('key', 'value', { ttlSeconds: 100 })).rejects.toMatchError(new cache_1.ApiError(400, 'NOT_ALLOWED', '"title":"Invalid operation"'));
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
describe('setIfNotExists', () => {
|
|
105
|
-
it('handles success', async () => {
|
|
106
|
-
const { cache, fetch } = buildCache();
|
|
107
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 'OK' }), status: 200 });
|
|
108
|
-
const result = await cache.setIfNotExists('key', 'value');
|
|
109
|
-
expect(result).toEqual('OK');
|
|
110
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
111
|
-
});
|
|
112
|
-
it('handles success when key exists', async () => {
|
|
113
|
-
const { cache, fetch } = buildCache();
|
|
114
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: null }), status: 200 });
|
|
115
|
-
const result = await cache.setIfNotExists('key', 'value');
|
|
116
|
-
expect(result).toBeNull();
|
|
117
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
118
|
-
});
|
|
119
|
-
it('handles success with ttl', async () => {
|
|
120
|
-
const { cache, fetch } = buildCache();
|
|
121
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 'OK' }), status: 200 });
|
|
122
|
-
await cache.setIfNotExists('key', 'value', { ttlSeconds: 100 });
|
|
123
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
124
|
-
});
|
|
125
|
-
it('handles failure', async () => {
|
|
126
|
-
const { cache, fetch } = buildCache();
|
|
127
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
128
|
-
await expect(cache.setIfNotExists('key', 'value', { ttlSeconds: 100 })).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
129
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
describe('get', () => {
|
|
133
|
-
it('handles success', async () => {
|
|
134
|
-
const { cache, fetch } = buildCache();
|
|
135
|
-
fetch.mockResolvedValueOnce({
|
|
136
|
-
ok: true,
|
|
137
|
-
text: async () => JSON.stringify({ response: 'asdfasdf' }),
|
|
138
|
-
status: 200
|
|
139
|
-
});
|
|
140
|
-
const result = await cache.get('key');
|
|
141
|
-
expect(result).toEqual('asdfasdf');
|
|
142
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
143
|
-
});
|
|
144
|
-
it('handles success when key does not exist', async () => {
|
|
145
|
-
const { cache, fetch } = buildCache();
|
|
146
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: null }), status: 200 });
|
|
147
|
-
const result = await cache.get('key');
|
|
148
|
-
expect(result).toBeNull();
|
|
149
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
150
|
-
});
|
|
151
|
-
it('handles failure', async () => {
|
|
152
|
-
const { cache, fetch } = buildCache();
|
|
153
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
154
|
-
await expect(cache.get('key')).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
155
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
describe('getAndSet', () => {
|
|
159
|
-
it('handles success', async () => {
|
|
160
|
-
const { cache, fetch } = buildCache();
|
|
161
|
-
fetch.mockResolvedValueOnce({
|
|
162
|
-
ok: true,
|
|
163
|
-
text: async () => JSON.stringify({ response: 'oldValue' }),
|
|
164
|
-
status: 200
|
|
165
|
-
});
|
|
166
|
-
const result = await cache.getAndSet('key', 'newValue');
|
|
167
|
-
expect(result).toEqual('oldValue');
|
|
168
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
169
|
-
});
|
|
170
|
-
it('handles success when key does not exist', async () => {
|
|
171
|
-
const { cache, fetch } = buildCache();
|
|
172
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: null }), status: 200 });
|
|
173
|
-
const result = await cache.getAndSet('key', 'value');
|
|
174
|
-
expect(result).toBeNull();
|
|
175
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
176
|
-
});
|
|
177
|
-
it('handles success with ttl', async () => {
|
|
178
|
-
const { cache, fetch } = buildCache();
|
|
179
|
-
fetch.mockResolvedValueOnce({
|
|
180
|
-
ok: true,
|
|
181
|
-
text: async () => JSON.stringify({ response: 'oldValue' }),
|
|
182
|
-
status: 200
|
|
183
|
-
});
|
|
184
|
-
await cache.getAndSet('key', 'newValue', { ttlSeconds: 100 });
|
|
185
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
186
|
-
});
|
|
187
|
-
it('handles failure', async () => {
|
|
188
|
-
const { cache, fetch } = buildCache();
|
|
189
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
190
|
-
await expect(cache.getAndSet('key', 'value', { ttlSeconds: 100 })).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
191
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
describe('incrementAndGet', () => {
|
|
195
|
-
it('handles success', async () => {
|
|
196
|
-
const { cache, fetch } = buildCache();
|
|
197
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 0 }), status: 200 });
|
|
198
|
-
const result = await cache.incrementAndGet('key');
|
|
199
|
-
expect(result).toEqual(0);
|
|
200
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
201
|
-
});
|
|
202
|
-
it('handles success with ttl', async () => {
|
|
203
|
-
const { cache, fetch } = buildCache();
|
|
204
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 0 }), status: 200 });
|
|
205
|
-
const result = await cache.incrementAndGet('key', { ttlSeconds: 100 });
|
|
206
|
-
expect(result).toEqual(0);
|
|
207
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
208
|
-
});
|
|
209
|
-
it('handles success when key exists', async () => {
|
|
210
|
-
const { cache, fetch } = buildCache();
|
|
211
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 11 }), status: 200 });
|
|
212
|
-
const result = await cache.incrementAndGet('key');
|
|
213
|
-
expect(result).toEqual(11);
|
|
214
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
215
|
-
});
|
|
216
|
-
it('handles failure', async () => {
|
|
217
|
-
const { cache, fetch } = buildCache();
|
|
218
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
219
|
-
await expect(cache.incrementAndGet('key')).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
220
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
221
|
-
});
|
|
222
|
-
});
|
|
223
|
-
describe('decrementAndGet', () => {
|
|
224
|
-
it('handles success', async () => {
|
|
225
|
-
const { cache, fetch } = buildCache();
|
|
226
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 0 }), status: 200 });
|
|
227
|
-
const result = await cache.decrementAndGet('key');
|
|
228
|
-
expect(result).toEqual(0);
|
|
229
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
230
|
-
});
|
|
231
|
-
it('handles success with ttl', async () => {
|
|
232
|
-
const { cache, fetch } = buildCache();
|
|
233
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 0 }), status: 200 });
|
|
234
|
-
const result = await cache.decrementAndGet('key', { ttlSeconds: 100 });
|
|
235
|
-
expect(result).toEqual(0);
|
|
236
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
237
|
-
});
|
|
238
|
-
it('handles success when key exists', async () => {
|
|
239
|
-
const { cache, fetch } = buildCache();
|
|
240
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 11 }), status: 200 });
|
|
241
|
-
const result = await cache.decrementAndGet('key');
|
|
242
|
-
expect(result).toEqual(11);
|
|
243
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
244
|
-
});
|
|
245
|
-
it('handles failure', async () => {
|
|
246
|
-
const { cache, fetch } = buildCache();
|
|
247
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
248
|
-
await expect(cache.decrementAndGet('key')).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
249
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
describe('delete', () => {
|
|
253
|
-
it('handles success', async () => {
|
|
254
|
-
const { cache, fetch } = buildCache();
|
|
255
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 1 }), status: 200 });
|
|
256
|
-
const result = await cache.delete('key');
|
|
257
|
-
expect(result).toEqual(1);
|
|
258
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
259
|
-
});
|
|
260
|
-
it('handles failure', async () => {
|
|
261
|
-
const { cache, fetch } = buildCache();
|
|
262
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
263
|
-
await expect(cache.delete('key')).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
264
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
265
|
-
});
|
|
266
|
-
});
|
|
267
|
-
describe('scan', () => {
|
|
268
|
-
it('handles success', async () => {
|
|
269
|
-
const { cache, fetch } = buildCache();
|
|
270
|
-
const expectedResponse = { cursor: '0', keys: ['key1', 'key2'] };
|
|
271
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify(expectedResponse), status: 200 });
|
|
272
|
-
const actualResponse = await cache.scan('key*');
|
|
273
|
-
expect(actualResponse).toEqual(expectedResponse);
|
|
274
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
275
|
-
});
|
|
276
|
-
it('handles success with cursor', async () => {
|
|
277
|
-
const { cache, fetch } = buildCache();
|
|
278
|
-
const expectedResponse = { cursor: '0', keys: ['key2'] };
|
|
279
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify(expectedResponse), status: 200 });
|
|
280
|
-
const actualResponse = await cache.scan('key*', { cursor: '1' });
|
|
281
|
-
expect(actualResponse).toEqual(expectedResponse);
|
|
282
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
283
|
-
});
|
|
284
|
-
it('handles success with count', async () => {
|
|
285
|
-
const { cache, fetch } = buildCache();
|
|
286
|
-
const expectedResponse = { cursor: '0', keys: ['key1'] };
|
|
287
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify(expectedResponse), status: 200 });
|
|
288
|
-
const actualResponse = await cache.scan('key*', { count: 1 });
|
|
289
|
-
expect(actualResponse).toEqual(expectedResponse);
|
|
290
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
291
|
-
});
|
|
292
|
-
it('handles failure', async () => {
|
|
293
|
-
const { cache, fetch } = buildCache();
|
|
294
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
295
|
-
await expect(cache.scan('key*', { cursor: '0', count: 2 })).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
296
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
describe('leftPush', () => {
|
|
300
|
-
it('handles success', async () => {
|
|
301
|
-
const { cache, fetch } = buildCache();
|
|
302
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 1 }), status: 200 });
|
|
303
|
-
const result = await cache.leftPush('list', 'value');
|
|
304
|
-
expect(result).toEqual(1);
|
|
305
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
306
|
-
});
|
|
307
|
-
it('handles failure', async () => {
|
|
308
|
-
const { cache, fetch } = buildCache();
|
|
309
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
310
|
-
await expect(cache.leftPush('list', 'value')).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
311
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
312
|
-
});
|
|
313
|
-
});
|
|
314
|
-
describe('rightPop', () => {
|
|
315
|
-
it('handles success', async () => {
|
|
316
|
-
const { cache, fetch } = buildCache();
|
|
317
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 'value' }), status: 200 });
|
|
318
|
-
const result = await cache.rightPop('list');
|
|
319
|
-
expect(result).toEqual('value');
|
|
320
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
321
|
-
});
|
|
322
|
-
it('handles success when key does not exist', async () => {
|
|
323
|
-
const { cache, fetch } = buildCache();
|
|
324
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: null }), status: 200 });
|
|
325
|
-
const result = await cache.rightPop('list');
|
|
326
|
-
expect(result).toBeNull();
|
|
327
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
328
|
-
});
|
|
329
|
-
it('handles failure', async () => {
|
|
330
|
-
const { cache, fetch } = buildCache();
|
|
331
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
332
|
-
await expect(cache.rightPop('list')).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
333
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
describe('listLength', () => {
|
|
337
|
-
it('handles success', async () => {
|
|
338
|
-
const { cache, fetch } = buildCache();
|
|
339
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 2 }), status: 200 });
|
|
340
|
-
const result = await cache.listLength('list');
|
|
341
|
-
expect(result).toBe(2);
|
|
342
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
343
|
-
});
|
|
344
|
-
it('handles success when key does not exist', async () => {
|
|
345
|
-
const { cache, fetch } = buildCache();
|
|
346
|
-
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 0 }), status: 200 });
|
|
347
|
-
const result = await cache.listLength('list');
|
|
348
|
-
expect(result).toBe(0);
|
|
349
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
350
|
-
});
|
|
351
|
-
it('handles failure', async () => {
|
|
352
|
-
const { cache, fetch } = buildCache();
|
|
353
|
-
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
354
|
-
await expect(cache.listLength('list')).rejects.toMatchError(new cache_1.ApiError(403, 'UNKNOWN_ERROR', 'Not allowed'));
|
|
355
|
-
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
356
|
-
});
|
|
357
|
-
});
|
|
358
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel.test.d.ts","sourceRoot":"","sources":["../../src/__test__/tunnel.test.ts"],"names":[],"mappings":""}
|