testcontainers 10.3.1 → 10.3.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/build/port-forwarder/port-forwarder.d.ts +12 -5
- package/build/port-forwarder/port-forwarder.js +64 -17
- package/build/port-forwarder/port-forwarder.js.map +1 -1
- package/build/reaper/reaper.js +1 -1
- package/build/reaper/reaper.js.map +1 -1
- package/build/test-containers.d.ts +1 -0
- package/build/test-containers.js +20 -1
- package/build/test-containers.js.map +1 -1
- package/build/utils/labels.d.ts +1 -0
- package/build/utils/labels.js +2 -1
- package/build/utils/labels.js.map +1 -1
- package/build/version.d.ts +1 -1
- package/build/version.js +1 -1
- package/package.json +1 -1
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import { SshConnection } from "ssh-remote-port-forward";
|
|
2
|
-
import { StartedTestContainer } from "../test-container";
|
|
3
2
|
export declare const SSHD_IMAGE: string;
|
|
4
|
-
|
|
3
|
+
declare class PortForwarder {
|
|
5
4
|
private readonly sshConnection;
|
|
6
|
-
private readonly
|
|
7
|
-
|
|
5
|
+
private readonly containerId;
|
|
6
|
+
private readonly networkId;
|
|
7
|
+
private readonly ipAddress;
|
|
8
|
+
private readonly networkName;
|
|
9
|
+
constructor(sshConnection: SshConnection, containerId: string, networkId: string, ipAddress: string, networkName: string);
|
|
8
10
|
exposeHostPort(port: number): Promise<void>;
|
|
11
|
+
getContainerId(): string;
|
|
9
12
|
getNetworkId(): string;
|
|
10
13
|
getIpAddress(): string;
|
|
11
|
-
private getNetworkName;
|
|
12
14
|
}
|
|
13
15
|
export declare class PortForwarderInstance {
|
|
16
|
+
private static readonly USERNAME;
|
|
17
|
+
private static readonly PASSWORD;
|
|
14
18
|
private static instance;
|
|
15
19
|
static isRunning(): boolean;
|
|
16
20
|
static getInstance(): Promise<PortForwarder>;
|
|
21
|
+
private static findPortForwarderContainer;
|
|
22
|
+
private static reuseInstance;
|
|
17
23
|
private static createInstance;
|
|
18
24
|
}
|
|
25
|
+
export {};
|
|
@@ -1,72 +1,119 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PortForwarderInstance = exports.
|
|
3
|
+
exports.PortForwarderInstance = exports.SSHD_IMAGE = void 0;
|
|
4
4
|
const ssh_remote_port_forward_1 = require("ssh-remote-port-forward");
|
|
5
5
|
const generic_container_1 = require("../generic-container/generic-container");
|
|
6
6
|
const common_1 = require("../common");
|
|
7
7
|
const container_runtime_1 = require("../container-runtime");
|
|
8
8
|
const reaper_1 = require("../reaper/reaper");
|
|
9
|
+
const labels_1 = require("../utils/labels");
|
|
9
10
|
exports.SSHD_IMAGE = process.env["SSHD_CONTAINER_IMAGE"] ?? "testcontainers/sshd:1.1.0";
|
|
10
11
|
class PortForwarder {
|
|
11
12
|
sshConnection;
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
containerId;
|
|
14
|
+
networkId;
|
|
15
|
+
ipAddress;
|
|
16
|
+
networkName;
|
|
17
|
+
constructor(sshConnection, containerId, networkId, ipAddress, networkName) {
|
|
14
18
|
this.sshConnection = sshConnection;
|
|
15
|
-
this.
|
|
19
|
+
this.containerId = containerId;
|
|
20
|
+
this.networkId = networkId;
|
|
21
|
+
this.ipAddress = ipAddress;
|
|
22
|
+
this.networkName = networkName;
|
|
16
23
|
}
|
|
17
24
|
async exposeHostPort(port) {
|
|
18
25
|
common_1.log.info(`Exposing host port ${port}...`);
|
|
19
26
|
await this.sshConnection.remoteForward("localhost", port);
|
|
20
27
|
common_1.log.info(`Exposed host port ${port}`);
|
|
21
28
|
}
|
|
29
|
+
getContainerId() {
|
|
30
|
+
return this.containerId;
|
|
31
|
+
}
|
|
22
32
|
getNetworkId() {
|
|
23
|
-
return this.
|
|
33
|
+
return this.networkId;
|
|
24
34
|
}
|
|
25
35
|
getIpAddress() {
|
|
26
|
-
return this.
|
|
27
|
-
}
|
|
28
|
-
getNetworkName() {
|
|
29
|
-
return this.container.getNetworkNames()[0];
|
|
36
|
+
return this.ipAddress;
|
|
30
37
|
}
|
|
31
38
|
}
|
|
32
|
-
exports.PortForwarder = PortForwarder;
|
|
33
39
|
class PortForwarderInstance {
|
|
40
|
+
static USERNAME = "root";
|
|
41
|
+
static PASSWORD = "root";
|
|
34
42
|
static instance;
|
|
35
43
|
static isRunning() {
|
|
36
44
|
return this.instance !== undefined;
|
|
37
45
|
}
|
|
38
46
|
static async getInstance() {
|
|
39
47
|
if (!this.instance) {
|
|
40
|
-
|
|
48
|
+
await (0, common_1.withFileLock)("testcontainers-node-sshd.lock", async () => {
|
|
49
|
+
const client = await (0, container_runtime_1.getContainerRuntimeClient)();
|
|
50
|
+
const reaper = await (0, reaper_1.getReaper)(client);
|
|
51
|
+
const sessionId = reaper.sessionId;
|
|
52
|
+
const portForwarderContainer = await this.findPortForwarderContainer(client, sessionId);
|
|
53
|
+
if (portForwarderContainer) {
|
|
54
|
+
this.instance = this.reuseInstance(client, portForwarderContainer, sessionId);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.instance = this.createInstance();
|
|
58
|
+
}
|
|
59
|
+
await this.instance;
|
|
60
|
+
});
|
|
41
61
|
}
|
|
42
62
|
return this.instance;
|
|
43
63
|
}
|
|
64
|
+
static async findPortForwarderContainer(client, sessionId) {
|
|
65
|
+
const containers = await client.container.list();
|
|
66
|
+
return containers.find((container) => container.State === "running" &&
|
|
67
|
+
container.Labels[labels_1.LABEL_TESTCONTAINERS_SSHD] === "true" &&
|
|
68
|
+
container.Labels[labels_1.LABEL_TESTCONTAINERS_SESSION_ID] === sessionId);
|
|
69
|
+
}
|
|
70
|
+
static async reuseInstance(client, container, sessionId) {
|
|
71
|
+
common_1.log.debug(`Reusing existing PortForwarder for session "${sessionId}"...`);
|
|
72
|
+
const host = client.info.containerRuntime.host;
|
|
73
|
+
const port = container.Ports.find((port) => port.PrivatePort == 22)?.PublicPort;
|
|
74
|
+
if (!port) {
|
|
75
|
+
throw new Error("Expected PortForwarder to map exposed port 22");
|
|
76
|
+
}
|
|
77
|
+
common_1.log.debug(`Connecting to Port Forwarder on "${host}:${port}"...`);
|
|
78
|
+
const connection = await (0, ssh_remote_port_forward_1.createSshConnection)({ host, port, username: "root", password: "root" });
|
|
79
|
+
common_1.log.debug(`Connected to Port Forwarder on "${host}:${port}"`);
|
|
80
|
+
connection.unref();
|
|
81
|
+
const containerId = container.Id;
|
|
82
|
+
const networks = Object.entries(container.NetworkSettings.Networks);
|
|
83
|
+
const networkName = networks[0][0];
|
|
84
|
+
const networkId = container.NetworkSettings.Networks[networkName].NetworkID;
|
|
85
|
+
const ipAddress = container.NetworkSettings.Networks[networkName].IPAddress;
|
|
86
|
+
return new PortForwarder(connection, containerId, networkId, ipAddress, networkName);
|
|
87
|
+
}
|
|
44
88
|
static async createInstance() {
|
|
45
89
|
common_1.log.debug(`Creating new Port Forwarder...`);
|
|
46
90
|
const client = await (0, container_runtime_1.getContainerRuntimeClient)();
|
|
47
91
|
const reaper = await (0, reaper_1.getReaper)(client);
|
|
48
|
-
const username = "root";
|
|
49
|
-
const password = new common_1.RandomUuid().nextUuid();
|
|
50
92
|
const containerPort = process.env["TESTCONTAINERS_SSHD_PORT"]
|
|
51
93
|
? { container: 22, host: Number(process.env["TESTCONTAINERS_SSHD_PORT"]) }
|
|
52
94
|
: 22;
|
|
53
95
|
const container = await new generic_container_1.GenericContainer(exports.SSHD_IMAGE)
|
|
54
96
|
.withName(`testcontainers-port-forwarder-${reaper.sessionId}`)
|
|
55
97
|
.withExposedPorts(containerPort)
|
|
56
|
-
.withEnvironment({ PASSWORD:
|
|
98
|
+
.withEnvironment({ PASSWORD: this.PASSWORD })
|
|
99
|
+
.withLabels({ [labels_1.LABEL_TESTCONTAINERS_SSHD]: "true" })
|
|
57
100
|
.withCommand([
|
|
58
101
|
"sh",
|
|
59
102
|
"-c",
|
|
60
|
-
`echo "${
|
|
103
|
+
`echo "${this.USERNAME}:$PASSWORD" | chpasswd && /usr/sbin/sshd -D -o PermitRootLogin=yes -o AddressFamily=inet -o GatewayPorts=yes -o AllowAgentForwarding=yes -o AllowTcpForwarding=yes -o KexAlgorithms=+diffie-hellman-group1-sha1 -o HostkeyAlgorithms=+ssh-rsa`,
|
|
61
104
|
])
|
|
62
105
|
.start();
|
|
63
106
|
const host = client.info.containerRuntime.host;
|
|
64
107
|
const port = container.getMappedPort(22);
|
|
65
108
|
common_1.log.debug(`Connecting to Port Forwarder on "${host}:${port}"...`);
|
|
66
|
-
const connection = await (0, ssh_remote_port_forward_1.createSshConnection)({ host, port, username, password });
|
|
109
|
+
const connection = await (0, ssh_remote_port_forward_1.createSshConnection)({ host, port, username: this.USERNAME, password: this.PASSWORD });
|
|
67
110
|
common_1.log.debug(`Connected to Port Forwarder on "${host}:${port}"`);
|
|
68
111
|
connection.unref();
|
|
69
|
-
|
|
112
|
+
const containerId = container.getId();
|
|
113
|
+
const networkName = container.getNetworkNames()[0];
|
|
114
|
+
const networkId = container.getNetworkId(networkName);
|
|
115
|
+
const ipAddress = container.getIpAddress(networkName);
|
|
116
|
+
return new PortForwarder(connection, containerId, networkId, ipAddress, networkName);
|
|
70
117
|
}
|
|
71
118
|
}
|
|
72
119
|
exports.PortForwarderInstance = PortForwarderInstance;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-forwarder.js","sourceRoot":"","sources":["../../src/port-forwarder/port-forwarder.ts"],"names":[],"mappings":";;;AAAA,qEAA6E;AAC7E,8EAA0E;
|
|
1
|
+
{"version":3,"file":"port-forwarder.js","sourceRoot":"","sources":["../../src/port-forwarder/port-forwarder.ts"],"names":[],"mappings":"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"}
|
package/build/reaper/reaper.js
CHANGED
|
@@ -32,7 +32,7 @@ async function getReaper(client) {
|
|
|
32
32
|
exports.getReaper = getReaper;
|
|
33
33
|
async function findReaperContainer(client) {
|
|
34
34
|
const containers = await client.container.list();
|
|
35
|
-
return containers.find((container) => container.Labels["org.testcontainers.ryuk"] === "true");
|
|
35
|
+
return containers.find((container) => container.State === "running" && container.Labels["org.testcontainers.ryuk"] === "true");
|
|
36
36
|
}
|
|
37
37
|
async function useExistingReaper(reaperContainer, sessionId, host) {
|
|
38
38
|
common_1.log.debug(`Reusing existing Reaper for session "${sessionId}"...`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reaper.js","sourceRoot":"","sources":["../../src/reaper/reaper.ts"],"names":[],"mappings":";;;AACA,8EAA0E;AAC1E,kDAA+C;AAC/C,6BAA6B;AAE7B,sCAAyE;AACzE,4CAAkE;AAErD,QAAA,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,2BAA2B,CAAC;AAU/F,IAAI,MAAc,CAAC;AACnB,IAAI,SAAiB,CAAC;AAEf,KAAK,UAAU,SAAS,CAAC,MAA8B;IAC5D,IAAI,MAAM,EAAE;QACV,OAAO,MAAM,CAAC;KACf;IAED,MAAM,GAAG,MAAM,IAAA,qBAAY,EAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,eAAe,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC1D,SAAS,GAAG,eAAe,EAAE,MAAM,CAAC,+BAA+B,CAAC,IAAI,IAAI,mBAAU,EAAE,CAAC,QAAQ,EAAE,CAAC;QAEpG,IAAI,OAAO,CAAC,GAAG,CAAC,4BAA4B,KAAK,MAAM,EAAE;YACvD,OAAO,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC;SACtC;aAAM,IAAI,eAAe,EAAE;YAC1B,OAAO,MAAM,iBAAiB,CAAC,eAAe,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;SAC/F;aAAM;YACL,OAAO,MAAM,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,CAAC;SACxF;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC;AApBD,8BAoBC;AAED,KAAK,UAAU,mBAAmB,CAAC,MAA8B;IAC/D,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IACjD,OAAO,UAAU,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"reaper.js","sourceRoot":"","sources":["../../src/reaper/reaper.ts"],"names":[],"mappings":"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"}
|
package/build/test-containers.js
CHANGED
|
@@ -2,10 +2,29 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TestContainers = void 0;
|
|
4
4
|
const port_forwarder_1 = require("./port-forwarder/port-forwarder");
|
|
5
|
+
const container_runtime_1 = require("./container-runtime");
|
|
6
|
+
const common_1 = require("./common");
|
|
5
7
|
class TestContainers {
|
|
6
8
|
static async exposeHostPorts(...ports) {
|
|
7
9
|
const portForwarder = await port_forwarder_1.PortForwarderInstance.getInstance();
|
|
8
|
-
await Promise.all(ports.map((port) => portForwarder.exposeHostPort(port))
|
|
10
|
+
await Promise.all(ports.map((port) => portForwarder.exposeHostPort(port).catch(async (err) => {
|
|
11
|
+
if (await this.isHostPortExposed(portForwarder.getContainerId(), port)) {
|
|
12
|
+
common_1.log.debug(`Host port ${port} is already exposed`);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
throw err;
|
|
16
|
+
}
|
|
17
|
+
})));
|
|
18
|
+
}
|
|
19
|
+
static async isHostPortExposed(portForwarderContainerId, hostPort) {
|
|
20
|
+
const client = await (0, container_runtime_1.getContainerRuntimeClient)();
|
|
21
|
+
const container = client.container.getById(portForwarderContainerId);
|
|
22
|
+
const { exitCode } = await client.container.exec(container, [
|
|
23
|
+
"sh",
|
|
24
|
+
"-c",
|
|
25
|
+
`netstat -tl | grep ${hostPort} | grep LISTEN`,
|
|
26
|
+
]);
|
|
27
|
+
return exitCode === 0;
|
|
9
28
|
}
|
|
10
29
|
}
|
|
11
30
|
exports.TestContainers = TestContainers;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-containers.js","sourceRoot":"","sources":["../src/test-containers.ts"],"names":[],"mappings":";;;AAAA,oEAAwE;
|
|
1
|
+
{"version":3,"file":"test-containers.js","sourceRoot":"","sources":["../src/test-containers.ts"],"names":[],"mappings":";;;AAAA,oEAAwE;AACxE,2DAAgE;AAChE,qCAA+B;AAE/B,MAAa,cAAc;IAClB,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,KAAe;QACpD,MAAM,aAAa,GAAG,MAAM,sCAAqB,CAAC,WAAW,EAAE,CAAC;QAEhE,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACjB,aAAa,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACrD,IAAI,MAAM,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,EAAE;gBACtE,YAAG,CAAC,KAAK,CAAC,aAAa,IAAI,qBAAqB,CAAC,CAAC;aACnD;iBAAM;gBACL,MAAM,GAAG,CAAC;aACX;QACH,CAAC,CAAC,CACH,CACF,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,wBAAgC,EAAE,QAAgB;QACvF,MAAM,MAAM,GAAG,MAAM,IAAA,6CAAyB,GAAE,CAAC;QACjD,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;QAErE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE;YAC1D,IAAI;YACJ,IAAI;YACJ,sBAAsB,QAAQ,gBAAgB;SAC/C,CAAC,CAAC;QAEH,OAAO,QAAQ,KAAK,CAAC,CAAC;IACxB,CAAC;CACF;AA7BD,wCA6BC"}
|
package/build/utils/labels.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ export declare const LABEL_TESTCONTAINERS = "org.testcontainers";
|
|
|
2
2
|
export declare const LABEL_TESTCONTAINERS_LANG = "org.testcontainers.lang";
|
|
3
3
|
export declare const LABEL_TESTCONTAINERS_VERSION = "org.testcontainers.version";
|
|
4
4
|
export declare const LABEL_TESTCONTAINERS_SESSION_ID = "org.testcontainers.session-id";
|
|
5
|
+
export declare const LABEL_TESTCONTAINERS_SSHD = "org.testcontainers.sshd";
|
|
5
6
|
export declare const LABEL_TESTCONTAINERS_CONTAINER_HASH = "org.testcontainers.container-hash";
|
|
6
7
|
export declare function createLabels(): Record<string, string>;
|
package/build/utils/labels.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createLabels = exports.LABEL_TESTCONTAINERS_CONTAINER_HASH = exports.LABEL_TESTCONTAINERS_SESSION_ID = exports.LABEL_TESTCONTAINERS_VERSION = exports.LABEL_TESTCONTAINERS_LANG = exports.LABEL_TESTCONTAINERS = void 0;
|
|
3
|
+
exports.createLabels = exports.LABEL_TESTCONTAINERS_CONTAINER_HASH = exports.LABEL_TESTCONTAINERS_SSHD = exports.LABEL_TESTCONTAINERS_SESSION_ID = exports.LABEL_TESTCONTAINERS_VERSION = exports.LABEL_TESTCONTAINERS_LANG = exports.LABEL_TESTCONTAINERS = void 0;
|
|
4
4
|
const version_1 = require("../version");
|
|
5
5
|
exports.LABEL_TESTCONTAINERS = "org.testcontainers";
|
|
6
6
|
exports.LABEL_TESTCONTAINERS_LANG = "org.testcontainers.lang";
|
|
7
7
|
exports.LABEL_TESTCONTAINERS_VERSION = "org.testcontainers.version";
|
|
8
8
|
exports.LABEL_TESTCONTAINERS_SESSION_ID = "org.testcontainers.session-id";
|
|
9
|
+
exports.LABEL_TESTCONTAINERS_SSHD = "org.testcontainers.sshd";
|
|
9
10
|
exports.LABEL_TESTCONTAINERS_CONTAINER_HASH = "org.testcontainers.container-hash";
|
|
10
11
|
function createLabels() {
|
|
11
12
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"labels.js","sourceRoot":"","sources":["../../src/utils/labels.ts"],"names":[],"mappings":";;;AAAA,wCAAyC;AAE5B,QAAA,oBAAoB,GAAG,oBAAoB,CAAC;AAC5C,QAAA,yBAAyB,GAAG,yBAAyB,CAAC;AACtD,QAAA,4BAA4B,GAAG,4BAA4B,CAAC;AAC5D,QAAA,+BAA+B,GAAG,+BAA+B,CAAC;AAClE,QAAA,mCAAmC,GAAG,mCAAmC,CAAC;AAEvF,SAAgB,YAAY;IAC1B,OAAO;QACL,CAAC,4BAAoB,CAAC,EAAE,MAAM;QAC9B,CAAC,iCAAyB,CAAC,EAAE,MAAM;QACnC,CAAC,oCAA4B,CAAC,EAAE,qBAAW;KAC5C,CAAC;AACJ,CAAC;AAND,oCAMC"}
|
|
1
|
+
{"version":3,"file":"labels.js","sourceRoot":"","sources":["../../src/utils/labels.ts"],"names":[],"mappings":";;;AAAA,wCAAyC;AAE5B,QAAA,oBAAoB,GAAG,oBAAoB,CAAC;AAC5C,QAAA,yBAAyB,GAAG,yBAAyB,CAAC;AACtD,QAAA,4BAA4B,GAAG,4BAA4B,CAAC;AAC5D,QAAA,+BAA+B,GAAG,+BAA+B,CAAC;AAClE,QAAA,yBAAyB,GAAG,yBAAyB,CAAC;AACtD,QAAA,mCAAmC,GAAG,mCAAmC,CAAC;AAEvF,SAAgB,YAAY;IAC1B,OAAO;QACL,CAAC,4BAAoB,CAAC,EAAE,MAAM;QAC9B,CAAC,iCAAyB,CAAC,EAAE,MAAM;QACnC,CAAC,oCAA4B,CAAC,EAAE,qBAAW;KAC5C,CAAC;AACJ,CAAC;AAND,oCAMC"}
|
package/build/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "10.3.
|
|
1
|
+
export declare const LIB_VERSION = "10.3.2";
|
package/build/version.js
CHANGED