@forge/cache 0.7.0-next.1 → 0.7.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 +6 -0
- package/out/__test__/cache.test.js +67 -22
- package/out/cache.d.ts +3 -0
- package/out/cache.d.ts.map +1 -1
- package/out/cache.js +20 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,4 +21,10 @@ const result = await cacheClient.decrementAndGet("hello");
|
|
|
21
21
|
const result = await cacheClient.delete("hello");
|
|
22
22
|
|
|
23
23
|
const result = await cacheClient.scan("hello*", { cursor: "10", count: 10 });
|
|
24
|
+
|
|
25
|
+
const result = await cacheClient.leftPush("list", "3");
|
|
26
|
+
|
|
27
|
+
const result = await cacheClient.rightPop("list");
|
|
28
|
+
|
|
29
|
+
const result = await cacheClient.listLength("list");
|
|
24
30
|
```
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
3
5
|
const api_1 = require("@forge/api");
|
|
4
6
|
const cache_1 = require("../cache");
|
|
7
|
+
jest.mock('node-fetch');
|
|
8
|
+
const fetchMock = node_fetch_1.default;
|
|
5
9
|
describe('connect', () => {
|
|
6
|
-
let fetchMock;
|
|
7
10
|
describe('v1', () => {
|
|
8
11
|
beforeEach(() => {
|
|
9
|
-
|
|
12
|
+
jest.resetAllMocks();
|
|
13
|
+
jest.clearAllMocks();
|
|
10
14
|
global['api'] = { requestRmsStore: fetchMock };
|
|
11
15
|
});
|
|
12
16
|
afterAll(() => {
|
|
@@ -18,12 +22,7 @@ describe('connect', () => {
|
|
|
18
22
|
});
|
|
19
23
|
});
|
|
20
24
|
describe('v2', () => {
|
|
21
|
-
let fetchMock;
|
|
22
|
-
let orgFetch;
|
|
23
25
|
beforeEach(() => {
|
|
24
|
-
fetchMock = jest.fn();
|
|
25
|
-
orgFetch = global['fetch'];
|
|
26
|
-
global['fetch'] = fetchMock;
|
|
27
26
|
global['__forge_runtime__'] = {
|
|
28
27
|
proxy: {
|
|
29
28
|
token: 'token',
|
|
@@ -39,9 +38,6 @@ describe('connect', () => {
|
|
|
39
38
|
}
|
|
40
39
|
};
|
|
41
40
|
});
|
|
42
|
-
afterAll(() => {
|
|
43
|
-
global['fetch'] = orgFetch;
|
|
44
|
-
});
|
|
45
41
|
it('chooses the v2 fetch based on runtime', async () => {
|
|
46
42
|
const cacheClient = (0, cache_1.connect)();
|
|
47
43
|
await cacheClient['client']('asdf');
|
|
@@ -50,16 +46,6 @@ describe('connect', () => {
|
|
|
50
46
|
});
|
|
51
47
|
});
|
|
52
48
|
describe('createFetch', () => {
|
|
53
|
-
let fetchMock;
|
|
54
|
-
let orgFetch;
|
|
55
|
-
beforeEach(() => {
|
|
56
|
-
fetchMock = jest.fn();
|
|
57
|
-
orgFetch = global['fetch'];
|
|
58
|
-
global['fetch'] = fetchMock;
|
|
59
|
-
});
|
|
60
|
-
afterAll(() => {
|
|
61
|
-
global['fetch'] = orgFetch;
|
|
62
|
-
});
|
|
63
49
|
it('fetch fails when rms config is not available', async () => {
|
|
64
50
|
global['__forge_runtime__'] = {
|
|
65
51
|
proxy: {
|
|
@@ -88,8 +74,8 @@ describe('createFetch', () => {
|
|
|
88
74
|
const fetch = (0, cache_1.createFetchRmsRuntimeV2)();
|
|
89
75
|
await fetch('path');
|
|
90
76
|
const [absoluteUrl, options] = (_a = fetchMock.mock.lastCall) !== null && _a !== void 0 ? _a : ['', {}];
|
|
91
|
-
expect(absoluteUrl).toEqual('https://
|
|
92
|
-
expect((options === null || options === void 0 ? void 0 : options.agent)['keepAlive']).toBeTruthy();
|
|
77
|
+
expect(absoluteUrl.toString()).toEqual('https://rms/path');
|
|
78
|
+
expect((options === null || options === void 0 ? void 0 : options.agent)['passthrough']['keepAlive']).toBeTruthy();
|
|
93
79
|
expect(options === null || options === void 0 ? void 0 : options.headers).toMatchObject({
|
|
94
80
|
Authorization: 'Bearer token',
|
|
95
81
|
Host: 'rockmelon-storage.dev.atl-paas.net',
|
|
@@ -305,4 +291,63 @@ describe('Cache', () => {
|
|
|
305
291
|
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
306
292
|
});
|
|
307
293
|
});
|
|
294
|
+
describe('leftPush', () => {
|
|
295
|
+
it('handles success', async () => {
|
|
296
|
+
const { cache, fetch } = buildCache();
|
|
297
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 1 }), status: 200 });
|
|
298
|
+
const result = await cache.leftPush('list', 'value');
|
|
299
|
+
expect(result).toEqual(1);
|
|
300
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
301
|
+
});
|
|
302
|
+
it('handles failure', async () => {
|
|
303
|
+
const { cache, fetch } = buildCache();
|
|
304
|
+
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
305
|
+
await expect(cache.leftPush('list', 'value')).rejects.toMatchError(new api_1.HttpError('403: Not allowed'));
|
|
306
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
describe('rightPop', () => {
|
|
310
|
+
it('handles success', async () => {
|
|
311
|
+
const { cache, fetch } = buildCache();
|
|
312
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 'value' }), status: 200 });
|
|
313
|
+
const result = await cache.rightPop('list');
|
|
314
|
+
expect(result).toEqual('value');
|
|
315
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
316
|
+
});
|
|
317
|
+
it('handles success when key does not exist', async () => {
|
|
318
|
+
const { cache, fetch } = buildCache();
|
|
319
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: null }), status: 200 });
|
|
320
|
+
const result = await cache.rightPop('list');
|
|
321
|
+
expect(result).toBeNull();
|
|
322
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
323
|
+
});
|
|
324
|
+
it('handles failure', async () => {
|
|
325
|
+
const { cache, fetch } = buildCache();
|
|
326
|
+
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
327
|
+
await expect(cache.rightPop('list')).rejects.toMatchError(new api_1.HttpError('403: Not allowed'));
|
|
328
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
describe('listLength', () => {
|
|
332
|
+
it('handles success', async () => {
|
|
333
|
+
const { cache, fetch } = buildCache();
|
|
334
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 2 }), status: 200 });
|
|
335
|
+
const result = await cache.listLength('list');
|
|
336
|
+
expect(result).toBe(2);
|
|
337
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
338
|
+
});
|
|
339
|
+
it('handles success when key does not exist', async () => {
|
|
340
|
+
const { cache, fetch } = buildCache();
|
|
341
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: 0 }), status: 200 });
|
|
342
|
+
const result = await cache.listLength('list');
|
|
343
|
+
expect(result).toBe(0);
|
|
344
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
345
|
+
});
|
|
346
|
+
it('handles failure', async () => {
|
|
347
|
+
const { cache, fetch } = buildCache();
|
|
348
|
+
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
349
|
+
await expect(cache.listLength('list')).rejects.toMatchError(new api_1.HttpError('403: Not allowed'));
|
|
350
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
351
|
+
});
|
|
352
|
+
});
|
|
308
353
|
});
|
package/out/cache.d.ts
CHANGED
|
@@ -26,6 +26,9 @@ export declare class Cache {
|
|
|
26
26
|
cursor?: string;
|
|
27
27
|
count?: number;
|
|
28
28
|
}): Promise<ScanResult>;
|
|
29
|
+
leftPush(key: string, value: string): Promise<number>;
|
|
30
|
+
rightPop(key: string): Promise<string | null>;
|
|
31
|
+
listLength(key: string): Promise<number>;
|
|
29
32
|
}
|
|
30
33
|
export declare function getFetchRmsRuntimeV1(): ((path: string, options?: RequestInit) => Promise<Response>) | undefined;
|
|
31
34
|
export declare function createFetchRmsRuntimeV2(): (path: string, options?: RequestInit) => Promise<Response>;
|
package/out/cache.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AACA,OAAkB,EAAE,WAAW,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAInF,oBAAY,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAC;AAEzE,oBAAY,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC;AAGF,wBAAsB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAYtE;AAED,qBAAa,KAAK;IACJ,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC;IAGtF,OAAO,CAAC,YAAY;IAUP,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5E,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;IAO9F,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAOxC,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;IAO3F,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO7C,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO7C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOpC,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;
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AACA,OAAkB,EAAE,WAAW,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAInF,oBAAY,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAC;AAEzE,oBAAY,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB,CAAC;AAGF,wBAAsB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAYtE;AAED,qBAAa,KAAK;IACJ,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC;IAGtF,OAAO,CAAC,YAAY;IAUP,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5E,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;IAO9F,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAOxC,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;IAO3F,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO7C,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO7C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOpC,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;IAOrF,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOrD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAO7C,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAMtD;AAED,wBAAgB,oBAAoB,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,SAAS,CAG/G;AAID,wBAAgB,uBAAuB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CA0BpG;AAED,wBAAgB,OAAO,UAItB"}
|
package/out/cache.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.connect = exports.createFetchRmsRuntimeV2 = exports.getFetchRmsRuntimeV1 = exports.Cache = exports.getResponseBody = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
const https_1 = require("https");
|
|
6
|
+
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
5
7
|
const api_1 = require("@forge/api");
|
|
6
8
|
async function getResponseBody(response) {
|
|
7
9
|
const responseText = await response.text();
|
|
@@ -68,6 +70,21 @@ class Cache {
|
|
|
68
70
|
const response = await this.client('rms/store/scan', this.buildRequest({ cursor, pattern, count }));
|
|
69
71
|
return await getResponseBody(response);
|
|
70
72
|
}
|
|
73
|
+
async leftPush(key, value) {
|
|
74
|
+
const response = await this.client('rms/store/lpush', this.buildRequest({ key, value }));
|
|
75
|
+
const { response: result } = await getResponseBody(response);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
async rightPop(key) {
|
|
79
|
+
const response = await this.client('rms/store/rpop', this.buildRequest({ key }));
|
|
80
|
+
const { response: result } = await getResponseBody(response);
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
async listLength(key) {
|
|
84
|
+
const response = await this.client('rms/store/llen', this.buildRequest({ key }));
|
|
85
|
+
const { response: result } = await getResponseBody(response);
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
71
88
|
}
|
|
72
89
|
exports.Cache = Cache;
|
|
73
90
|
function getFetchRmsRuntimeV1() {
|
|
@@ -82,8 +99,9 @@ function createFetchRmsRuntimeV2() {
|
|
|
82
99
|
if (!(rms === null || rms === void 0 ? void 0 : rms.url) || !(rms === null || rms === void 0 ? void 0 : rms.host)) {
|
|
83
100
|
throw new Error('RMS config not available.');
|
|
84
101
|
}
|
|
85
|
-
const
|
|
86
|
-
|
|
102
|
+
const rmsAgent = new String('FORGE_PRODUCT_REQUEST');
|
|
103
|
+
rmsAgent['passthrough'] = agent;
|
|
104
|
+
return await (0, node_fetch_1.default)(new URL(path, 'https://rms/'), Object.assign(Object.assign({}, options), { agent: rmsAgent, headers: Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.headers), { Authorization: `Bearer ${proxy.token}`, Host: rms.host, 'x-b3-traceid': tracing.traceId, 'x-b3-spanid': tracing.spanId }) }));
|
|
87
105
|
};
|
|
88
106
|
}
|
|
89
107
|
exports.createFetchRmsRuntimeV2 = createFetchRmsRuntimeV2;
|