@forge/cache 0.3.2-next.0 → 0.4.0-next.2
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 +4 -0
- package/out/__test__/cache.test.js +80 -1
- package/out/cache.d.ts +8 -1
- package/out/cache.d.ts.map +1 -1
- package/out/cache.js +11 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -12,9 +12,13 @@ const result = await cacheClient.setIfNotExists("hello", "3", { ttlSeconds: 10 }
|
|
|
12
12
|
|
|
13
13
|
const result = await cacheClient.get("hello");
|
|
14
14
|
|
|
15
|
+
const result = await cacheClient.getAndSet("hello", "3", { ttlSeconds: 10 });
|
|
16
|
+
|
|
15
17
|
const result = await cacheClient.incrementAndGet("hello");
|
|
16
18
|
|
|
17
19
|
const result = await cacheClient.decrementAndGet("hello");
|
|
18
20
|
|
|
19
21
|
const result = await cacheClient.delete("hello");
|
|
22
|
+
|
|
23
|
+
const result = await cacheClient.scan("hello*", { cursor: "10", count: 10 });
|
|
20
24
|
```
|
|
@@ -155,11 +155,22 @@ describe('Cache', () => {
|
|
|
155
155
|
describe('get', () => {
|
|
156
156
|
it('handles success', async () => {
|
|
157
157
|
const { cache, fetch } = buildCache();
|
|
158
|
-
fetch.mockResolvedValueOnce({
|
|
158
|
+
fetch.mockResolvedValueOnce({
|
|
159
|
+
ok: true,
|
|
160
|
+
text: async () => JSON.stringify({ response: 'asdfasdf' }),
|
|
161
|
+
status: 200
|
|
162
|
+
});
|
|
159
163
|
const result = await cache.get('key');
|
|
160
164
|
expect(result).toEqual('asdfasdf');
|
|
161
165
|
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
162
166
|
});
|
|
167
|
+
it('handles success when key does not exist', async () => {
|
|
168
|
+
const { cache, fetch } = buildCache();
|
|
169
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: null }), status: 200 });
|
|
170
|
+
const result = await cache.get('key');
|
|
171
|
+
expect(result).toBeNull();
|
|
172
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
173
|
+
});
|
|
163
174
|
it('handles failure', async () => {
|
|
164
175
|
const { cache, fetch } = buildCache();
|
|
165
176
|
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
@@ -167,6 +178,42 @@ describe('Cache', () => {
|
|
|
167
178
|
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
168
179
|
});
|
|
169
180
|
});
|
|
181
|
+
describe('getAndSet', () => {
|
|
182
|
+
it('handles success', async () => {
|
|
183
|
+
const { cache, fetch } = buildCache();
|
|
184
|
+
fetch.mockResolvedValueOnce({
|
|
185
|
+
ok: true,
|
|
186
|
+
text: async () => JSON.stringify({ response: 'oldValue' }),
|
|
187
|
+
status: 200
|
|
188
|
+
});
|
|
189
|
+
const result = await cache.getAndSet('key', 'newValue');
|
|
190
|
+
expect(result).toEqual('oldValue');
|
|
191
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
192
|
+
});
|
|
193
|
+
it('handles success when key does not exist', async () => {
|
|
194
|
+
const { cache, fetch } = buildCache();
|
|
195
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify({ response: null }), status: 200 });
|
|
196
|
+
const result = await cache.getAndSet('key', 'value');
|
|
197
|
+
expect(result).toBeNull();
|
|
198
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
199
|
+
});
|
|
200
|
+
it('handles success with ttl', async () => {
|
|
201
|
+
const { cache, fetch } = buildCache();
|
|
202
|
+
fetch.mockResolvedValueOnce({
|
|
203
|
+
ok: true,
|
|
204
|
+
text: async () => JSON.stringify({ response: 'oldValue' }),
|
|
205
|
+
status: 200
|
|
206
|
+
});
|
|
207
|
+
await cache.getAndSet('key', 'newValue', { ttlSeconds: 100 });
|
|
208
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
209
|
+
});
|
|
210
|
+
it('handles failure', async () => {
|
|
211
|
+
const { cache, fetch } = buildCache();
|
|
212
|
+
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
213
|
+
await expect(cache.getAndSet('key', 'value', { ttlSeconds: 100 })).rejects.toMatchError(new api_1.HttpError('403: Not allowed'));
|
|
214
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
215
|
+
});
|
|
216
|
+
});
|
|
170
217
|
describe('incrementAndGet', () => {
|
|
171
218
|
it('handles success', async () => {
|
|
172
219
|
const { cache, fetch } = buildCache();
|
|
@@ -226,4 +273,36 @@ describe('Cache', () => {
|
|
|
226
273
|
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
227
274
|
});
|
|
228
275
|
});
|
|
276
|
+
describe('scan', () => {
|
|
277
|
+
it('handles success', async () => {
|
|
278
|
+
const { cache, fetch } = buildCache();
|
|
279
|
+
const expectedResponse = { cursor: '0', keys: ['key1', 'key2'] };
|
|
280
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify(expectedResponse), status: 200 });
|
|
281
|
+
const actualResponse = await cache.scan('key*');
|
|
282
|
+
expect(actualResponse).toEqual(expectedResponse);
|
|
283
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
284
|
+
});
|
|
285
|
+
it('handles success with cursor', async () => {
|
|
286
|
+
const { cache, fetch } = buildCache();
|
|
287
|
+
const expectedResponse = { cursor: '0', keys: ['key2'] };
|
|
288
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify(expectedResponse), status: 200 });
|
|
289
|
+
const actualResponse = await cache.scan('key*', { cursor: '1' });
|
|
290
|
+
expect(actualResponse).toEqual(expectedResponse);
|
|
291
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
292
|
+
});
|
|
293
|
+
it('handles success with count', async () => {
|
|
294
|
+
const { cache, fetch } = buildCache();
|
|
295
|
+
const expectedResponse = { cursor: '0', keys: ['key1'] };
|
|
296
|
+
fetch.mockResolvedValueOnce({ ok: true, text: async () => JSON.stringify(expectedResponse), status: 200 });
|
|
297
|
+
const actualResponse = await cache.scan('key*', { count: 1 });
|
|
298
|
+
expect(actualResponse).toEqual(expectedResponse);
|
|
299
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
300
|
+
});
|
|
301
|
+
it('handles failure', async () => {
|
|
302
|
+
const { cache, fetch } = buildCache();
|
|
303
|
+
fetch.mockResolvedValueOnce({ ok: false, text: async () => 'Not allowed', status: 403 });
|
|
304
|
+
await expect(cache.scan('key*', { cursor: '0', count: 2 })).rejects.toMatchError(new api_1.HttpError('403: Not allowed'));
|
|
305
|
+
expect(fetch.mock.lastCall).toMatchSnapshot();
|
|
306
|
+
});
|
|
307
|
+
});
|
|
229
308
|
});
|
package/out/cache.d.ts
CHANGED
|
@@ -11,10 +11,17 @@ export declare class Cache {
|
|
|
11
11
|
setIfNotExists(key: string, value: string, opt?: {
|
|
12
12
|
ttlSeconds: number;
|
|
13
13
|
}): Promise<'OK' | null>;
|
|
14
|
-
get(key: string): Promise<string>;
|
|
14
|
+
get(key: string): Promise<string | null>;
|
|
15
|
+
getAndSet(key: string, value: string, opt?: {
|
|
16
|
+
ttlSeconds: number;
|
|
17
|
+
}): Promise<string | null>;
|
|
15
18
|
incrementAndGet(key: string): Promise<number>;
|
|
16
19
|
decrementAndGet(key: string): Promise<number>;
|
|
17
20
|
delete(key: string): Promise<number>;
|
|
21
|
+
scan(pattern: string, opt?: {
|
|
22
|
+
cursor?: string;
|
|
23
|
+
count?: number;
|
|
24
|
+
}): Promise<JSON>;
|
|
18
25
|
}
|
|
19
26
|
export declare function getFetchRmsRuntimeV1(): ((path: string, options?: RequestInit) => Promise<Response>) | undefined;
|
|
20
27
|
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,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAC;AAGzE,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,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,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,CAAC;AAGzE,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,IAAI,CAAC;CAM7F;AAED,wBAAgB,oBAAoB,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,SAAS,CAE/G;AAID,wBAAgB,uBAAuB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CA2BpG;AAED,wBAAgB,OAAO,UAItB"}
|
package/out/cache.js
CHANGED
|
@@ -40,7 +40,12 @@ class Cache {
|
|
|
40
40
|
}
|
|
41
41
|
async get(key) {
|
|
42
42
|
const response = await this.client('rms/store/get', this.buildRequest({ key }));
|
|
43
|
-
const {
|
|
43
|
+
const { response: result } = await getResponseBody(response);
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
async getAndSet(key, value, opt) {
|
|
47
|
+
const response = await this.client('rms/store/getset', this.buildRequest(Object.assign({ key, value }, opt)));
|
|
48
|
+
const { response: result } = await getResponseBody(response);
|
|
44
49
|
return result;
|
|
45
50
|
}
|
|
46
51
|
async incrementAndGet(key) {
|
|
@@ -58,6 +63,11 @@ class Cache {
|
|
|
58
63
|
const { response: result } = await getResponseBody(response);
|
|
59
64
|
return result;
|
|
60
65
|
}
|
|
66
|
+
async scan(pattern, opt) {
|
|
67
|
+
const { cursor, count } = opt || {};
|
|
68
|
+
const response = await this.client('rms/store/scan', this.buildRequest({ cursor, pattern, count }));
|
|
69
|
+
return await getResponseBody(response);
|
|
70
|
+
}
|
|
61
71
|
}
|
|
62
72
|
exports.Cache = Cache;
|
|
63
73
|
function getFetchRmsRuntimeV1() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forge/cache",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0-next.2",
|
|
4
4
|
"description": "Forge Cache methods",
|
|
5
5
|
"author": "Atlassian",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"@types/node": "14.18.59",
|
|
19
|
-
"@types/node-fetch": "^2.6.
|
|
19
|
+
"@types/node-fetch": "^2.6.5",
|
|
20
20
|
"node-fetch": "2.7.0"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@forge/api": "^2.19.1-next.
|
|
23
|
+
"@forge/api": "^2.19.1-next.1"
|
|
24
24
|
}
|
|
25
25
|
}
|