@toa.io/extensions.stash 0.20.0-dev.19 → 0.20.0-dev.20
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/package.json +2 -2
- package/transpiled/Aspect.d.ts +17 -0
- package/transpiled/Aspect.fixtures.d.ts +4 -0
- package/transpiled/Aspect.fixtures.js +7 -0
- package/transpiled/Aspect.fixtures.js.map +1 -0
- package/transpiled/Aspect.js +49 -0
- package/transpiled/Aspect.js.map +1 -0
- package/transpiled/Aspect.test.d.ts +1 -0
- package/transpiled/Aspect.test.js +102 -0
- package/transpiled/Aspect.test.js.map +1 -0
- package/transpiled/Connection.d.ts +7 -0
- package/transpiled/Connection.fixtures.d.ts +10 -0
- package/transpiled/Connection.fixtures.js +18 -0
- package/transpiled/Connection.fixtures.js.map +1 -0
- package/transpiled/Connection.js +19 -0
- package/transpiled/Connection.js.map +1 -0
- package/transpiled/Connection.test.d.ts +1 -0
- package/transpiled/Connection.test.js +40 -0
- package/transpiled/Connection.test.js.map +1 -0
- package/transpiled/extension.d.ts +12 -0
- package/transpiled/extension.js +35 -0
- package/transpiled/extension.js.map +1 -0
- package/transpiled/index.d.ts +1 -0
- package/transpiled/index.js +18 -0
- package/transpiled/index.js.map +1 -0
- package/transpiled/tsconfig.tsbuildinfo +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/extensions.stash",
|
|
3
|
-
"version": "0.20.0-dev.
|
|
3
|
+
"version": "0.20.0-dev.20",
|
|
4
4
|
"description": "Toa Stash",
|
|
5
5
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
"preset": "ts-jest",
|
|
30
30
|
"testEnvironment": "node"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "52c962bc17b71f3e7890ec53870f8b93fda720a0"
|
|
33
33
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Connector, type extensions } from '@toa.io/core';
|
|
2
|
+
import type { Connection } from './Connection';
|
|
3
|
+
export declare class Aspect extends Connector implements extensions.Aspect {
|
|
4
|
+
readonly name = "stash";
|
|
5
|
+
private readonly redis;
|
|
6
|
+
private readonly redlock;
|
|
7
|
+
constructor(connection: Connection);
|
|
8
|
+
invoke(method: 'store', key: string, value: object): Promise<void>;
|
|
9
|
+
invoke(method: 'fetch', key: string): Promise<object>;
|
|
10
|
+
invoke(method: 'lock', key: string | string[], routine: Routine): Promise<void>;
|
|
11
|
+
invoke(method: string, ...args: unknown[]): Promise<any>;
|
|
12
|
+
private store;
|
|
13
|
+
private fetch;
|
|
14
|
+
private lock;
|
|
15
|
+
}
|
|
16
|
+
type Routine = () => Promise<void>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Aspect.fixtures.js","sourceRoot":"","sources":["../source/Aspect.fixtures.ts"],"names":[],"mappings":";;;AAAa,QAAA,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IACpC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC;CACtC,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Aspect = void 0;
|
|
7
|
+
const redlock_1 = __importDefault(require("redlock"));
|
|
8
|
+
const msgpackr_1 = require("msgpackr");
|
|
9
|
+
const core_1 = require("@toa.io/core");
|
|
10
|
+
class Aspect extends core_1.Connector {
|
|
11
|
+
name = 'stash';
|
|
12
|
+
redis;
|
|
13
|
+
redlock;
|
|
14
|
+
constructor(connection) {
|
|
15
|
+
super();
|
|
16
|
+
this.redis = connection.redis;
|
|
17
|
+
this.redlock = new redlock_1.default([this.redis]);
|
|
18
|
+
this.depends(connection);
|
|
19
|
+
}
|
|
20
|
+
async invoke(method, ...args) {
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
22
|
+
// @ts-expect-error
|
|
23
|
+
if (typeof this.redis[method] === 'function')
|
|
24
|
+
return this.redis[method](...args);
|
|
25
|
+
if (method === 'store')
|
|
26
|
+
await this.store(args[0], args[1], ...args.slice(2));
|
|
27
|
+
if (method === 'fetch')
|
|
28
|
+
return await this.fetch(args[0]);
|
|
29
|
+
if (method === 'lock')
|
|
30
|
+
await this.lock(args[0], args[1]);
|
|
31
|
+
}
|
|
32
|
+
async store(key, value, ...args) {
|
|
33
|
+
const buffer = (0, msgpackr_1.encode)(value);
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
35
|
+
// @ts-expect-error
|
|
36
|
+
await this.redis.set(key, buffer, ...args);
|
|
37
|
+
}
|
|
38
|
+
async fetch(key) {
|
|
39
|
+
const buffer = await this.redis.getBuffer(key);
|
|
40
|
+
return buffer === null ? null : (0, msgpackr_1.decode)(buffer);
|
|
41
|
+
}
|
|
42
|
+
async lock(key, routine) {
|
|
43
|
+
if (typeof key === 'string')
|
|
44
|
+
key = [key];
|
|
45
|
+
await this.redlock.using(key, 5000, routine);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.Aspect = Aspect;
|
|
49
|
+
//# sourceMappingURL=Aspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Aspect.js","sourceRoot":"","sources":["../source/Aspect.ts"],"names":[],"mappings":";;;;;;AAAA,sDAA6B;AAC7B,uCAAyC;AACzC,uCAAyD;AAIzD,MAAa,MAAO,SAAQ,gBAAS;IACnB,IAAI,GAAG,OAAO,CAAA;IACb,KAAK,CAAO;IACZ,OAAO,CAAS;IAEjC,YAAoB,UAAsB;QACxC,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAA;QAC7B,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAExC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;IAC1B,CAAC;IAMM,KAAK,CAAC,MAAM,CAAE,MAAc,EAAE,GAAG,IAAe;QACrD,6DAA6D;QAC7D,mBAAmB;QACnB,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,UAAU;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;QAEhF,IAAI,MAAM,KAAK,OAAO;YAAE,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAW,EAAE,IAAI,CAAC,CAAC,CAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;QAEhG,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAW,CAAC,CAAA;QAElE,IAAI,MAAM,KAAK,MAAM;YAAE,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAW,EAAE,IAAI,CAAC,CAAC,CAAwB,CAAC,CAAA;IAC3F,CAAC;IAEO,KAAK,CAAC,KAAK,CAAE,GAAW,EAAE,KAAa,EAAE,GAAG,IAAe;QACjE,MAAM,MAAM,GAAG,IAAA,iBAAM,EAAC,KAAK,CAAC,CAAA;QAE5B,6DAA6D;QAC7D,mBAAmB;QACnB,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,CAAA;IAC5C,CAAC;IAEO,KAAK,CAAC,KAAK,CAAE,GAAW;QAC9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAE9C,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAA,iBAAM,EAAC,MAAM,CAAC,CAAA;IAChD,CAAC;IAEO,KAAK,CAAC,IAAI,CAAE,GAAsB,EAAE,OAAgB;QAC1D,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QAExC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAC9C,CAAC;CACF;AAjDD,wBAiDC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
const redlock_1 = __importDefault(require("redlock"));
|
|
30
|
+
const msgpackr_1 = require("msgpackr");
|
|
31
|
+
const randomstring_1 = require("randomstring");
|
|
32
|
+
const Aspect_1 = require("./Aspect");
|
|
33
|
+
const mock = __importStar(require("./Connection.fixtures"));
|
|
34
|
+
jest.mock('redlock');
|
|
35
|
+
let aspect;
|
|
36
|
+
let connection;
|
|
37
|
+
let redis;
|
|
38
|
+
let redlock;
|
|
39
|
+
const key = (0, randomstring_1.generate)();
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
jest.clearAllMocks();
|
|
42
|
+
connection = new mock.Connection();
|
|
43
|
+
redis = connection.redis;
|
|
44
|
+
aspect = new Aspect_1.Aspect(connection);
|
|
45
|
+
const m = redlock_1.default.mock;
|
|
46
|
+
redlock = redlock_1.default.mock.instances[0];
|
|
47
|
+
});
|
|
48
|
+
it('should depend on Connection', async () => {
|
|
49
|
+
expect(connection.link).toHaveBeenCalledWith(aspect);
|
|
50
|
+
});
|
|
51
|
+
it('should set', async () => {
|
|
52
|
+
const value = (0, randomstring_1.generate)();
|
|
53
|
+
await aspect.invoke('set', key, value);
|
|
54
|
+
expect(redis.set).toHaveBeenCalledWith(key, value);
|
|
55
|
+
});
|
|
56
|
+
it('should get', async () => {
|
|
57
|
+
const value = await aspect.invoke('get', key);
|
|
58
|
+
expect(redis.get).toHaveBeenCalledWith(key);
|
|
59
|
+
expect(value).toStrictEqual(await redis.get.mock.results[0].value);
|
|
60
|
+
});
|
|
61
|
+
describe('buffers', () => {
|
|
62
|
+
it.each([
|
|
63
|
+
['object', { [(0, randomstring_1.generate)()]: (0, randomstring_1.generate)() }],
|
|
64
|
+
['array', [(0, randomstring_1.generate)(), (0, randomstring_1.generate)()]]
|
|
65
|
+
])('should encode %s', async (_, value) => {
|
|
66
|
+
await aspect.invoke('store', key, value);
|
|
67
|
+
const buffer = (0, msgpackr_1.encode)(value);
|
|
68
|
+
expect(redis.set).toHaveBeenCalledWith(key, buffer);
|
|
69
|
+
});
|
|
70
|
+
it('should pass arguments', async () => {
|
|
71
|
+
const value = [1, 2];
|
|
72
|
+
const buffer = (0, msgpackr_1.encode)(value);
|
|
73
|
+
await aspect.invoke('store', key, value, 'EX', 1000);
|
|
74
|
+
expect(redis.set).toHaveBeenCalledWith(key, buffer, 'EX', 1000);
|
|
75
|
+
});
|
|
76
|
+
it.each([
|
|
77
|
+
['object', { [(0, randomstring_1.generate)()]: (0, randomstring_1.generate)() }],
|
|
78
|
+
['array', [(0, randomstring_1.generate)(), (0, randomstring_1.generate)()]]
|
|
79
|
+
])('should decode %s', async (_, value) => {
|
|
80
|
+
const buffer = (0, msgpackr_1.encode)(value);
|
|
81
|
+
redis.getBuffer.mockImplementationOnce(async () => buffer);
|
|
82
|
+
const output = await aspect.invoke('fetch', key);
|
|
83
|
+
expect(redis.getBuffer).toHaveBeenCalledWith(key);
|
|
84
|
+
expect(output).toStrictEqual(value);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
it('should create DLM', async () => {
|
|
88
|
+
expect(redlock_1.default).toHaveBeenCalledWith([redis]);
|
|
89
|
+
});
|
|
90
|
+
it('should acquire lock', async () => {
|
|
91
|
+
const keys = [(0, randomstring_1.generate)(), (0, randomstring_1.generate)()];
|
|
92
|
+
const callback = jest.fn();
|
|
93
|
+
await aspect.invoke('lock', keys, callback);
|
|
94
|
+
expect(redlock.using).toHaveBeenCalledWith(keys, 5000, callback);
|
|
95
|
+
});
|
|
96
|
+
it('should handle non-array key', async () => {
|
|
97
|
+
const key = (0, randomstring_1.generate)();
|
|
98
|
+
const callback = jest.fn();
|
|
99
|
+
await aspect.invoke('lock', key, callback);
|
|
100
|
+
expect(redlock.using).toHaveBeenCalledWith([key], 5000, callback);
|
|
101
|
+
});
|
|
102
|
+
//# sourceMappingURL=Aspect.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Aspect.test.js","sourceRoot":"","sources":["../source/Aspect.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/// <reference types="jest" />
|
|
2
|
+
import type * as redis from 'ioredis';
|
|
3
|
+
export declare const Redis: jest.Mock<typeof redis.Cluster, any>;
|
|
4
|
+
export declare const Connection: jest.Mock<{
|
|
5
|
+
redis: typeof redis.Cluster;
|
|
6
|
+
link: jest.Mock<any, any>;
|
|
7
|
+
}, []>;
|
|
8
|
+
export declare const ioredis: {
|
|
9
|
+
Redis: jest.Mock<typeof redis.Cluster, any>;
|
|
10
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ioredis = exports.Connection = exports.Redis = void 0;
|
|
4
|
+
const randomstring_1 = require("randomstring");
|
|
5
|
+
exports.Redis = jest.fn(() => ({
|
|
6
|
+
connect: jest.fn(async () => undefined),
|
|
7
|
+
disconnect: jest.fn(),
|
|
8
|
+
get: jest.fn(async () => (0, randomstring_1.generate)()),
|
|
9
|
+
getBuffer: jest.fn(async () => Buffer.from((0, randomstring_1.generate)())),
|
|
10
|
+
set: jest.fn(async () => undefined),
|
|
11
|
+
on: jest.fn()
|
|
12
|
+
}));
|
|
13
|
+
exports.Connection = jest.fn(() => ({
|
|
14
|
+
redis: new exports.Redis(),
|
|
15
|
+
link: jest.fn()
|
|
16
|
+
}));
|
|
17
|
+
exports.ioredis = { Redis: exports.Redis };
|
|
18
|
+
//# sourceMappingURL=Connection.fixtures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Connection.fixtures.js","sourceRoot":"","sources":["../source/Connection.fixtures.ts"],"names":[],"mappings":";;;AAAA,+CAAuC;AAG1B,QAAA,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IAClC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC;IACvC,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE;IACrB,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAA,uBAAQ,GAAE,CAAC;IACpC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAA,uBAAQ,GAAE,CAAC,CAAC;IACvD,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,SAAS,CAAC;IACnC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE;CACd,CAAC,CAA+C,CAAA;AAEpC,QAAA,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IACvC,KAAK,EAAE,IAAI,aAAK,EAAE;IAClB,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;CAChB,CAAC,CAAC,CAAA;AAEU,QAAA,OAAO,GAAG,EAAE,KAAK,EAAL,aAAK,EAAE,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Connection = void 0;
|
|
4
|
+
const ioredis_1 = require("ioredis");
|
|
5
|
+
const core_1 = require("@toa.io/core");
|
|
6
|
+
class Connection extends core_1.Connector {
|
|
7
|
+
redis;
|
|
8
|
+
constructor(url, locator) {
|
|
9
|
+
super();
|
|
10
|
+
const keyPrefix = `${locator.namespace}:${locator.name}:`;
|
|
11
|
+
const options = { keyPrefix, enableReadyCheck: true };
|
|
12
|
+
this.redis = new ioredis_1.Redis(url, options);
|
|
13
|
+
}
|
|
14
|
+
async close() {
|
|
15
|
+
this.redis.disconnect();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.Connection = Connection;
|
|
19
|
+
//# sourceMappingURL=Connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Connection.js","sourceRoot":"","sources":["../source/Connection.ts"],"names":[],"mappings":";;;AAAA,qCAAoD;AACpD,uCAAsD;AAEtD,MAAa,UAAW,SAAQ,gBAAS;IACvB,KAAK,CAAO;IAE5B,YAAoB,GAAW,EAAE,OAAgB;QAC/C,KAAK,EAAE,CAAA;QAEP,MAAM,SAAS,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,GAAG,CAAA;QACzD,MAAM,OAAO,GAAmB,EAAE,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAA;QAErE,IAAI,CAAC,KAAK,GAAG,IAAI,eAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACtC,CAAC;IAEkB,KAAK,CAAC,KAAK;QAC5B,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAA;IACzB,CAAC;CACF;AAfD,gCAeC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const randomstring_1 = require("randomstring");
|
|
4
|
+
const Connection_1 = require("./Connection");
|
|
5
|
+
const core_1 = require("@toa.io/core");
|
|
6
|
+
const Connection_fixtures_1 = require("./Connection.fixtures");
|
|
7
|
+
jest.mock('ioredis', () => ({
|
|
8
|
+
Redis: jest.fn((nodes, options) => new Connection_fixtures_1.Redis(nodes, options))
|
|
9
|
+
}));
|
|
10
|
+
let connection;
|
|
11
|
+
let cluster;
|
|
12
|
+
const url = (0, randomstring_1.generate)();
|
|
13
|
+
const locator = {
|
|
14
|
+
namespace: (0, randomstring_1.generate)(),
|
|
15
|
+
name: (0, randomstring_1.generate)()
|
|
16
|
+
};
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
jest.clearAllMocks();
|
|
19
|
+
connection = new Connection_1.Connection(url, locator);
|
|
20
|
+
cluster = Connection_fixtures_1.Redis.mock.results[0].value;
|
|
21
|
+
});
|
|
22
|
+
it('should be instance of Connector', async () => {
|
|
23
|
+
expect(connection).toBeInstanceOf(core_1.Connector);
|
|
24
|
+
});
|
|
25
|
+
it('should connect', async () => {
|
|
26
|
+
const keyPrefix = `${locator.namespace}:${locator.name}:`;
|
|
27
|
+
const options = { keyPrefix, enableReadyCheck: true };
|
|
28
|
+
expect(Connection_fixtures_1.Redis).toHaveBeenCalledWith(url, options);
|
|
29
|
+
// await connection.connect()
|
|
30
|
+
//
|
|
31
|
+
// expect(cluster.connect).toHaveBeenCalled()
|
|
32
|
+
});
|
|
33
|
+
it('should disconnect', async () => {
|
|
34
|
+
await connection.disconnect();
|
|
35
|
+
expect(cluster.disconnect).toHaveBeenCalled();
|
|
36
|
+
});
|
|
37
|
+
it('should expose cluster', async () => {
|
|
38
|
+
expect(connection.redis).toStrictEqual(cluster);
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=Connection.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Connection.test.js","sourceRoot":"","sources":["../source/Connection.test.ts"],"names":[],"mappings":";;AAAA,+CAAuC;AACvC,6CAAyC;AACzC,uCAAsD;AACtD,+DAA6C;AAG7C,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1B,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,KAAe,EAAE,OAA6B,EAAE,EAAE,CAAC,IAAI,2BAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;CAC9F,CAAC,CAAC,CAAA;AAEH,IAAI,UAAsB,CAAA;AAC1B,IAAI,OAAyC,CAAA;AAE7C,MAAM,GAAG,GAAG,IAAA,uBAAQ,GAAE,CAAA;AAEtB,MAAM,OAAO,GAAG;IACd,SAAS,EAAE,IAAA,uBAAQ,GAAE;IACrB,IAAI,EAAE,IAAA,uBAAQ,GAAE;CACK,CAAA;AAEvB,UAAU,CAAC,GAAG,EAAE;IACd,IAAI,CAAC,aAAa,EAAE,CAAA;IAEpB,UAAU,GAAG,IAAI,uBAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IACzC,OAAO,GAAG,2BAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AACvC,CAAC,CAAC,CAAA;AAEF,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;IAC/C,MAAM,CAAC,UAAU,CAAC,CAAC,cAAc,CAAC,gBAAS,CAAC,CAAA;AAC9C,CAAC,CAAC,CAAA;AAEF,EAAE,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;IAC9B,MAAM,SAAS,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,GAAG,CAAA;IACzD,MAAM,OAAO,GAAyB,EAAE,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAA;IAE3E,MAAM,CAAC,2BAAK,CAAC,CAAC,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAEhD,6BAA6B;IAC7B,EAAE;IACF,6CAA6C;AAC/C,CAAC,CAAC,CAAA;AAEF,EAAE,CAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;IACjC,MAAM,UAAU,CAAC,UAAU,EAAE,CAAA;IAE7B,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,gBAAgB,EAAE,CAAA;AAC/C,CAAC,CAAC,CAAA;AAEF,EAAE,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;IACrC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAA;AACjD,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { uris } from '@toa.io/pointer';
|
|
2
|
+
import type { Locator, extensions } from '@toa.io/core';
|
|
3
|
+
import type { context } from '@toa.io/norm';
|
|
4
|
+
import type * as operations from '@toa.io/operations';
|
|
5
|
+
export declare class Factory implements extensions.Factory {
|
|
6
|
+
aspect(locator: Locator): extensions.Aspect;
|
|
7
|
+
private url;
|
|
8
|
+
}
|
|
9
|
+
export declare function deployment(instances: context.Dependency[], annotation: Annotation): Dependency;
|
|
10
|
+
type Dependency = operations.deployment.Dependency;
|
|
11
|
+
type Annotation = uris.URIs | string;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deployment = exports.Factory = void 0;
|
|
4
|
+
const pointer_1 = require("@toa.io/pointer");
|
|
5
|
+
const Aspect_1 = require("./Aspect");
|
|
6
|
+
const Connection_1 = require("./Connection");
|
|
7
|
+
class Factory {
|
|
8
|
+
aspect(locator) {
|
|
9
|
+
const url = this.url();
|
|
10
|
+
const connection = new Connection_1.Connection(url, locator);
|
|
11
|
+
return new Aspect_1.Aspect(connection);
|
|
12
|
+
}
|
|
13
|
+
url() {
|
|
14
|
+
if (process.env.TOA_DEV === '1')
|
|
15
|
+
return 'redis://localhost';
|
|
16
|
+
const url = process.env[URL_VARIABLE];
|
|
17
|
+
if (url === undefined)
|
|
18
|
+
throw new Error(`${URL_VARIABLE} is not set`);
|
|
19
|
+
return url;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.Factory = Factory;
|
|
23
|
+
function deployment(instances, annotation) {
|
|
24
|
+
const pointer = pointer_1.uris.construct(annotation);
|
|
25
|
+
const variables = {};
|
|
26
|
+
for (const instance of instances) {
|
|
27
|
+
const resolution = pointer_1.uris.resolve(instance.locator, pointer);
|
|
28
|
+
const variable = { name: URL_VARIABLE, value: resolution.url.href };
|
|
29
|
+
variables[instance.locator.label] = [variable];
|
|
30
|
+
}
|
|
31
|
+
return { variables };
|
|
32
|
+
}
|
|
33
|
+
exports.deployment = deployment;
|
|
34
|
+
const URL_VARIABLE = 'TOA_STASH';
|
|
35
|
+
//# sourceMappingURL=extension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension.js","sourceRoot":"","sources":["../source/extension.ts"],"names":[],"mappings":";;;AAAA,6CAAsC;AACtC,qCAAiC;AACjC,6CAAyC;AAKzC,MAAa,OAAO;IACX,MAAM,CAAE,OAAgB;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACtB,MAAM,UAAU,GAAG,IAAI,uBAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAE/C,OAAO,IAAI,eAAM,CAAC,UAAU,CAAC,CAAA;IAC/B,CAAC;IAEO,GAAG;QACT,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,GAAG;YAAE,OAAO,mBAAmB,CAAA;QAE3D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAErC,IAAI,GAAG,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,GAAG,YAAY,aAAa,CAAC,CAAA;QAEpE,OAAO,GAAG,CAAA;IACZ,CAAC;CACF;AAjBD,0BAiBC;AAED,SAAgB,UAAU,CAAE,SAA+B,EAAE,UAAsB;IACjF,MAAM,OAAO,GAAG,cAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;IAC1C,MAAM,SAAS,GAAc,EAAE,CAAA;IAE/B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;QAChC,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;QAC1D,MAAM,QAAQ,GAAa,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;QAE7E,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;KAC/C;IAED,OAAO,EAAE,SAAS,EAAE,CAAA;AACtB,CAAC;AAZD,gCAYC;AAED,MAAM,YAAY,GAAG,WAAW,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './extension';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./extension"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA2B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":"4.9.5"}
|