@event-driven-io/emmett-testcontainers 0.43.0-beta.3 → 0.43.0-beta.30
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 +239 -0
- package/dist/index.cjs +327 -346
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -26
- package/dist/index.d.ts +31 -26
- package/dist/index.js +305 -340
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -1,362 +1,327 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
import { EventStoreDBClient } from "@eventstore/db-client";
|
|
2
|
+
import { InProcessLock } from "@event-driven-io/emmett";
|
|
3
|
+
import { AbstractStartedContainer, GenericContainer, Wait } from "testcontainers";
|
|
4
|
+
import { MongoDBContainer } from "@testcontainers/mongodb";
|
|
5
|
+
import { PostgreSqlContainer } from "@testcontainers/postgresql";
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
7
|
+
//#region ../almanac/dist/logger-DnrSjS8d.js
|
|
8
|
+
const LogLevel = {
|
|
9
|
+
default: "info",
|
|
10
|
+
silent: "silent",
|
|
11
|
+
trace: "trace",
|
|
12
|
+
debug: "debug",
|
|
13
|
+
info: "info",
|
|
14
|
+
warn: "warn",
|
|
15
|
+
error: "error",
|
|
16
|
+
fatal: "fatal"
|
|
17
|
+
};
|
|
18
|
+
const shouldLog = (logLevel, definedLogLevel) => {
|
|
19
|
+
definedLogLevel ??= LogLevel.default;
|
|
20
|
+
switch (definedLogLevel) {
|
|
21
|
+
case "fatal": return logLevel === LogLevel.fatal;
|
|
22
|
+
case "error": return [LogLevel.fatal, LogLevel.error].includes(logLevel);
|
|
23
|
+
case "warn": return [
|
|
24
|
+
LogLevel.fatal,
|
|
25
|
+
LogLevel.error,
|
|
26
|
+
LogLevel.warn
|
|
27
|
+
].includes(logLevel);
|
|
28
|
+
case "info": return [
|
|
29
|
+
LogLevel.fatal,
|
|
30
|
+
LogLevel.error,
|
|
31
|
+
LogLevel.warn,
|
|
32
|
+
LogLevel.info
|
|
33
|
+
].includes(logLevel);
|
|
34
|
+
case "debug": return [
|
|
35
|
+
LogLevel.fatal,
|
|
36
|
+
LogLevel.error,
|
|
37
|
+
LogLevel.warn,
|
|
38
|
+
LogLevel.info,
|
|
39
|
+
LogLevel.debug
|
|
40
|
+
].includes(logLevel);
|
|
41
|
+
case "trace": return [
|
|
42
|
+
LogLevel.fatal,
|
|
43
|
+
LogLevel.error,
|
|
44
|
+
LogLevel.warn,
|
|
45
|
+
LogLevel.info,
|
|
46
|
+
LogLevel.debug,
|
|
47
|
+
LogLevel.trace
|
|
48
|
+
].includes(logLevel);
|
|
49
|
+
case "silent": return false;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const logEvent = (eventName, data, eventMetadata) => {
|
|
53
|
+
return {
|
|
54
|
+
name: eventName,
|
|
55
|
+
data,
|
|
56
|
+
metadata: {
|
|
57
|
+
...eventMetadata,
|
|
58
|
+
timestamp: eventMetadata.timestamp ?? Date.now()
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
const message = (level, body, data, eventMetadata) => {
|
|
63
|
+
if (data === void 0) return logEvent(body, { body }, {
|
|
64
|
+
level,
|
|
65
|
+
...eventMetadata
|
|
66
|
+
});
|
|
67
|
+
const eventData = { body };
|
|
68
|
+
if (data.error !== void 0) eventData.error = data.error;
|
|
69
|
+
if (data.attributes !== void 0) eventData.attributes = data.attributes;
|
|
70
|
+
return logEvent(body, eventData, {
|
|
71
|
+
level,
|
|
72
|
+
...eventMetadata
|
|
73
|
+
});
|
|
35
74
|
};
|
|
75
|
+
const forLevel = (level) => (msgOrObj, msgOrMetadata, eventMetadata) => {
|
|
76
|
+
if (typeof msgOrObj === "string") return logEvent(msgOrObj, { body: msgOrObj }, {
|
|
77
|
+
level,
|
|
78
|
+
...typeof msgOrMetadata === "string" ? eventMetadata : msgOrMetadata
|
|
79
|
+
});
|
|
80
|
+
const msg = typeof msgOrMetadata === "string" ? msgOrMetadata : void 0;
|
|
81
|
+
const overrides = eventMetadata ?? (typeof msgOrMetadata === "string" ? void 0 : msgOrMetadata);
|
|
82
|
+
if (msgOrObj instanceof Error) return logEvent(msg ?? "", {
|
|
83
|
+
error: msgOrObj,
|
|
84
|
+
body: msg
|
|
85
|
+
}, {
|
|
86
|
+
level,
|
|
87
|
+
...overrides
|
|
88
|
+
});
|
|
89
|
+
const { eventName, ...attributes } = msgOrObj;
|
|
90
|
+
return logEvent(typeof eventName === "string" ? eventName : msg ?? "", {
|
|
91
|
+
attributes,
|
|
92
|
+
body: msg
|
|
93
|
+
}, {
|
|
94
|
+
level,
|
|
95
|
+
...overrides
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
const LogEvent = Object.assign(logEvent, {
|
|
99
|
+
message,
|
|
100
|
+
fatal: forLevel("fatal"),
|
|
101
|
+
error: forLevel("error"),
|
|
102
|
+
warn: forLevel("warn"),
|
|
103
|
+
info: forLevel("info"),
|
|
104
|
+
debug: forLevel("debug"),
|
|
105
|
+
trace: forLevel("trace"),
|
|
106
|
+
silent: forLevel("silent")
|
|
107
|
+
});
|
|
108
|
+
const logger = (options) => {
|
|
109
|
+
const { event: sink, minLevel } = options;
|
|
110
|
+
return (event) => {
|
|
111
|
+
if (event.metadata.level === "silent" || !shouldLog(event.metadata.level, minLevel)) return;
|
|
112
|
+
sink(event);
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
const noopLogger = logger({ event: () => {} });
|
|
36
116
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const taskPromise = task({
|
|
74
|
-
ack: resolveTask
|
|
75
|
-
});
|
|
76
|
-
taskPromise.then(resolve).catch((err) => {
|
|
77
|
-
failTask(err);
|
|
78
|
-
reject(err);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
};
|
|
82
|
-
this.queue.push({ task: taskWithContext, options });
|
|
83
|
-
if (!this.isProcessing) {
|
|
84
|
-
this.ensureProcessing();
|
|
85
|
-
}
|
|
86
|
-
},
|
|
87
|
-
{ deadline: this.options.maxTaskIdleTime }
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
ensureProcessing() {
|
|
91
|
-
if (this.isProcessing) return;
|
|
92
|
-
this.isProcessing = true;
|
|
93
|
-
this.processQueue();
|
|
94
|
-
}
|
|
95
|
-
processQueue() {
|
|
96
|
-
try {
|
|
97
|
-
while (this.activeTasks < this.options.maxActiveTasks && this.queue.length > 0) {
|
|
98
|
-
const item = this.takeFirstAvailableItem();
|
|
99
|
-
if (item === null) return;
|
|
100
|
-
const groupId = item.options?.taskGroupId;
|
|
101
|
-
if (groupId) {
|
|
102
|
-
this.activeGroups.add(groupId);
|
|
103
|
-
}
|
|
104
|
-
this.activeTasks++;
|
|
105
|
-
void this.executeItem(item);
|
|
106
|
-
}
|
|
107
|
-
} catch (error) {
|
|
108
|
-
console.error(error);
|
|
109
|
-
throw error;
|
|
110
|
-
} finally {
|
|
111
|
-
this.isProcessing = false;
|
|
112
|
-
if (this.hasItemsToProcess() && this.activeTasks < this.options.maxActiveTasks) {
|
|
113
|
-
this.ensureProcessing();
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
async executeItem({ task, options }) {
|
|
118
|
-
try {
|
|
119
|
-
await task();
|
|
120
|
-
} finally {
|
|
121
|
-
this.activeTasks--;
|
|
122
|
-
if (options && options.taskGroupId) {
|
|
123
|
-
this.activeGroups.delete(options.taskGroupId);
|
|
124
|
-
}
|
|
125
|
-
this.ensureProcessing();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
takeFirstAvailableItem = () => {
|
|
129
|
-
const taskIndex = this.queue.findIndex(
|
|
130
|
-
(item2) => !item2.options?.taskGroupId || !this.activeGroups.has(item2.options.taskGroupId)
|
|
131
|
-
);
|
|
132
|
-
if (taskIndex === -1) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
const [item] = this.queue.splice(taskIndex, 1);
|
|
136
|
-
return item ?? null;
|
|
137
|
-
};
|
|
138
|
-
hasItemsToProcess = () => this.queue.findIndex(
|
|
139
|
-
(item) => !item.options?.taskGroupId || !this.activeGroups.has(item.options.taskGroupId)
|
|
140
|
-
) !== -1;
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region ../almanac/dist/spanLogEvent-ByQosuDu.js
|
|
119
|
+
const bigIntReplacer = (_key, value) => {
|
|
120
|
+
return typeof value === "bigint" ? value.toString() : value;
|
|
121
|
+
};
|
|
122
|
+
const dateReplacer = (_key, value) => {
|
|
123
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
124
|
+
};
|
|
125
|
+
const errorReplacer = (_key, value) => value instanceof Error ? {
|
|
126
|
+
type: value.constructor.name || "error",
|
|
127
|
+
message: value.message,
|
|
128
|
+
stack: value.stack
|
|
129
|
+
} : value;
|
|
130
|
+
const isFirstLetterNumeric = (str) => {
|
|
131
|
+
const c = str.charCodeAt(0);
|
|
132
|
+
return c >= 48 && c <= 57;
|
|
133
|
+
};
|
|
134
|
+
const isFirstLetterNumericOrMinus = (str) => {
|
|
135
|
+
const c = str.charCodeAt(0);
|
|
136
|
+
return c >= 48 && c <= 57 || c === 45;
|
|
137
|
+
};
|
|
138
|
+
const bigIntReviver = (_key, value, context) => {
|
|
139
|
+
if (typeof value === "number" && Number.isInteger(value) && !Number.isSafeInteger(value)) try {
|
|
140
|
+
return BigInt(context?.source ?? value.toString());
|
|
141
|
+
} catch {
|
|
142
|
+
return value;
|
|
143
|
+
}
|
|
144
|
+
if (typeof value === "string" && value.length > 15) {
|
|
145
|
+
if (isFirstLetterNumericOrMinus(value)) {
|
|
146
|
+
const num = Number(value);
|
|
147
|
+
if (Number.isFinite(num) && !Number.isSafeInteger(num)) try {
|
|
148
|
+
return BigInt(value);
|
|
149
|
+
} catch {}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return value;
|
|
141
153
|
};
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (!taskStarted) {
|
|
149
|
-
reject(
|
|
150
|
-
new Error("Task was not started within the maximum waiting time")
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
}, maxWaitingTime);
|
|
154
|
-
executor((value) => {
|
|
155
|
-
taskStarted = true;
|
|
156
|
-
if (timeoutId) {
|
|
157
|
-
clearTimeout(timeoutId);
|
|
158
|
-
}
|
|
159
|
-
timeoutId = null;
|
|
160
|
-
resolve(value);
|
|
161
|
-
}, reject);
|
|
162
|
-
});
|
|
154
|
+
const dateReviver = (_key, value) => {
|
|
155
|
+
if (typeof value === "string" && value.length === 24 && isFirstLetterNumeric(value) && value[10] === "T" && value[23] === "Z") {
|
|
156
|
+
const date = new Date(value);
|
|
157
|
+
if (!isNaN(date.getTime())) return date;
|
|
158
|
+
}
|
|
159
|
+
return value;
|
|
163
160
|
};
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
});
|
|
169
|
-
const locks = /* @__PURE__ */ new Map();
|
|
170
|
-
return {
|
|
171
|
-
async acquire({ lockId }) {
|
|
172
|
-
await new Promise((resolve, reject) => {
|
|
173
|
-
taskProcessor.enqueue(
|
|
174
|
-
({ ack }) => {
|
|
175
|
-
locks.set(lockId, ack);
|
|
176
|
-
resolve();
|
|
177
|
-
return Promise.resolve();
|
|
178
|
-
},
|
|
179
|
-
{ taskGroupId: lockId }
|
|
180
|
-
).catch(reject);
|
|
181
|
-
});
|
|
182
|
-
},
|
|
183
|
-
async tryAcquire({ lockId }) {
|
|
184
|
-
if (locks.has(lockId)) {
|
|
185
|
-
return false;
|
|
186
|
-
}
|
|
187
|
-
await this.acquire({ lockId });
|
|
188
|
-
return true;
|
|
189
|
-
},
|
|
190
|
-
release({ lockId }) {
|
|
191
|
-
const ack = locks.get(lockId);
|
|
192
|
-
if (ack === void 0) {
|
|
193
|
-
return Promise.resolve(true);
|
|
194
|
-
}
|
|
195
|
-
locks.delete(lockId);
|
|
196
|
-
ack();
|
|
197
|
-
return Promise.resolve(true);
|
|
198
|
-
},
|
|
199
|
-
async withAcquire(handle, { lockId }) {
|
|
200
|
-
return taskProcessor.enqueue(
|
|
201
|
-
async ({ ack }) => {
|
|
202
|
-
locks.set(lockId, ack);
|
|
203
|
-
try {
|
|
204
|
-
return await handle();
|
|
205
|
-
} finally {
|
|
206
|
-
locks.delete(lockId);
|
|
207
|
-
ack();
|
|
208
|
-
}
|
|
209
|
-
},
|
|
210
|
-
{ taskGroupId: lockId }
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
};
|
|
161
|
+
const composeJSONReplacers = (...replacers) => {
|
|
162
|
+
const filteredReplacers = replacers.filter((r) => r !== void 0);
|
|
163
|
+
if (filteredReplacers.length === 0) return void 0;
|
|
164
|
+
return (key, value) => filteredReplacers.reduce((accValue, replacer) => replacer(key, accValue), value);
|
|
214
165
|
};
|
|
215
|
-
|
|
166
|
+
const composeJSONRevivers = (...revivers) => {
|
|
167
|
+
const filteredRevivers = revivers.filter((r) => r !== void 0);
|
|
168
|
+
if (filteredRevivers.length === 0) return void 0;
|
|
169
|
+
return (key, value, context) => filteredRevivers.reduce((accValue, reviver) => reviver(key, accValue, context), value);
|
|
170
|
+
};
|
|
171
|
+
const JSONReplacer = (opts) => composeJSONReplacers(opts?.replacer, opts?.failOnBigIntSerialization !== true ? JSONReplacers.bigInt : void 0, opts?.useDefaultDateSerialization !== true ? JSONReplacers.date : void 0, opts?.skipErrorSerialization !== true ? JSONReplacers.error : void 0);
|
|
172
|
+
const JSONReviver = (opts) => composeJSONRevivers(opts?.reviver, opts?.parseBigInts === true ? JSONRevivers.bigInt : void 0, opts?.parseDates === true ? JSONRevivers.date : void 0);
|
|
173
|
+
const JSONReplacers = {
|
|
174
|
+
bigInt: bigIntReplacer,
|
|
175
|
+
date: dateReplacer,
|
|
176
|
+
error: errorReplacer
|
|
177
|
+
};
|
|
178
|
+
const JSONRevivers = {
|
|
179
|
+
bigInt: bigIntReviver,
|
|
180
|
+
date: dateReviver
|
|
181
|
+
};
|
|
182
|
+
const jsonSerializer = (options) => {
|
|
183
|
+
const defaultReplacer = JSONReplacer(options);
|
|
184
|
+
const defaultReviver = JSONReviver(options);
|
|
185
|
+
const defaultFormat = options?.format ?? "compact";
|
|
186
|
+
const defaultSafe = options?.safe ?? false;
|
|
187
|
+
return {
|
|
188
|
+
serialize: (object, serializerOptions) => {
|
|
189
|
+
const replacer = serializerOptions ? JSONReplacer(serializerOptions) : defaultReplacer;
|
|
190
|
+
const indent = (serializerOptions?.format ?? defaultFormat) === "pretty" ? 2 : void 0;
|
|
191
|
+
if (serializerOptions?.safe ?? defaultSafe) try {
|
|
192
|
+
return JSON.stringify(object, replacer, indent);
|
|
193
|
+
} catch (e) {
|
|
194
|
+
return `{"__serializationError":${JSON.stringify(String(e))}}`;
|
|
195
|
+
}
|
|
196
|
+
return JSON.stringify(object, replacer, indent);
|
|
197
|
+
},
|
|
198
|
+
deserialize: (payload, deserializerOptions) => JSON.parse(payload, deserializerOptions ? JSONReviver(deserializerOptions) : defaultReviver)
|
|
199
|
+
};
|
|
200
|
+
};
|
|
201
|
+
const JSONSerializer = Object.assign(jsonSerializer(), { from: (options) => options?.serialization?.serializer ?? (options?.serialization?.options ? jsonSerializer(options?.serialization?.options) : JSONSerializer) });
|
|
216
202
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
203
|
+
//#endregion
|
|
204
|
+
//#region ../almanac/dist/console-Bn5yW7XZ.js
|
|
205
|
+
const consoleMethodFor = (level) => {
|
|
206
|
+
switch (level) {
|
|
207
|
+
case "fatal":
|
|
208
|
+
case "error": return console.error;
|
|
209
|
+
case "warn": return console.warn;
|
|
210
|
+
case "debug": return console.debug;
|
|
211
|
+
case "trace": return console.trace;
|
|
212
|
+
default: return console.log;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
const consoleLogger = logger({ event: (event) => {
|
|
216
|
+
const write = consoleMethodFor(event.metadata.level);
|
|
217
|
+
const extra = event.data.error ?? (event.data.attributes && Object.keys(event.data.attributes).length ? event.data.attributes : void 0);
|
|
218
|
+
if (event.data.body !== void 0 && extra !== void 0) write(event.data.body, extra);
|
|
219
|
+
else if (event.data.body !== void 0) write(event.data.body);
|
|
220
|
+
else if (extra !== void 0) write(extra);
|
|
221
|
+
else write("");
|
|
222
|
+
} });
|
|
223
|
+
|
|
224
|
+
//#endregion
|
|
225
|
+
//#region src/eventStore/eventStoreDBContainer.ts
|
|
226
|
+
const EVENTSTOREDB_PORT = 2113;
|
|
227
|
+
const EVENTSTOREDB_IMAGE_NAME = "eventstore/eventstore";
|
|
228
|
+
const EVENTSTOREDB_IMAGE_TAG = "24.10.0-bookworm-slim";
|
|
229
|
+
const EVENTSTOREDB_ARM64_IMAGE_TAG = "24.10.0-alpha-arm64v8";
|
|
230
|
+
const EVENTSTOREDB_DEFAULT_IMAGE = `${EVENTSTOREDB_IMAGE_NAME}:${process.arch !== "arm64" ? EVENTSTOREDB_IMAGE_TAG : EVENTSTOREDB_ARM64_IMAGE_TAG}`;
|
|
231
|
+
const defaultEventStoreDBContainerOptions = {
|
|
232
|
+
disableProjections: false,
|
|
233
|
+
isSecure: false,
|
|
234
|
+
useFileStorage: false,
|
|
235
|
+
withReuse: false
|
|
234
236
|
};
|
|
235
237
|
var EventStoreDBContainer = class extends GenericContainer {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
Wait.forAll([Wait.forHealthCheck(), Wait.forListeningPorts()])
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
async start() {
|
|
261
|
-
return new StartedEventStoreDBContainer(await super.start());
|
|
262
|
-
}
|
|
238
|
+
constructor(image = EVENTSTOREDB_DEFAULT_IMAGE, options = defaultEventStoreDBContainerOptions) {
|
|
239
|
+
super(image);
|
|
240
|
+
const environment = {
|
|
241
|
+
...!options.disableProjections ? { EVENTSTORE_RUN_PROJECTIONS: "ALL" } : {},
|
|
242
|
+
...!options.isSecure ? { EVENTSTORE_INSECURE: "true" } : {},
|
|
243
|
+
...options.useFileStorage ? {
|
|
244
|
+
EVENTSTORE_MEM_DB: "false",
|
|
245
|
+
EVENTSTORE_DB: "/data/integration-tests"
|
|
246
|
+
} : {},
|
|
247
|
+
EVENTSTORE_CLUSTER_SIZE: "1",
|
|
248
|
+
EVENTSTORE_START_STANDARD_PROJECTIONS: "true",
|
|
249
|
+
EVENTSTORE_NODE_PORT: `${EVENTSTOREDB_PORT}`,
|
|
250
|
+
EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP: "true"
|
|
251
|
+
};
|
|
252
|
+
this.withEnvironment(environment).withExposedPorts(EVENTSTOREDB_PORT);
|
|
253
|
+
if (options.withReuse) this.withReuse();
|
|
254
|
+
this.withWaitStrategy(Wait.forAll([Wait.forHealthCheck(), Wait.forListeningPorts()]));
|
|
255
|
+
}
|
|
256
|
+
async start() {
|
|
257
|
+
return new StartedEventStoreDBContainer(await super.start());
|
|
258
|
+
}
|
|
263
259
|
};
|
|
264
260
|
var StartedEventStoreDBContainer = class extends AbstractStartedContainer {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
261
|
+
constructor(container) {
|
|
262
|
+
super(container);
|
|
263
|
+
}
|
|
264
|
+
getConnectionString() {
|
|
265
|
+
return `esdb://${this.getHost()}:${this.getMappedPort(2113)}?tls=false`;
|
|
266
|
+
}
|
|
267
|
+
getClient() {
|
|
268
|
+
return EventStoreDBClient.connectionString(this.getConnectionString());
|
|
269
|
+
}
|
|
274
270
|
};
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
return startedContainer;
|
|
290
|
-
},
|
|
291
|
-
{ lockId: "SharedEventStoreDBTestContainer" }
|
|
292
|
-
);
|
|
293
|
-
var getSharedTestEventStoreDBClient = async () => {
|
|
294
|
-
return (await getSharedEventStoreDBTestContainer()).getClient();
|
|
271
|
+
let container = null;
|
|
272
|
+
let startedContainer = null;
|
|
273
|
+
let startedCount = 0;
|
|
274
|
+
const lock = InProcessLock();
|
|
275
|
+
const getSharedEventStoreDBTestContainer = () => lock.withAcquire(async () => {
|
|
276
|
+
if (startedContainer) return startedContainer;
|
|
277
|
+
if (!container) container = new EventStoreDBContainer(EVENTSTOREDB_DEFAULT_IMAGE);
|
|
278
|
+
startedContainer = await container.start();
|
|
279
|
+
startedCount++;
|
|
280
|
+
container.withLogConsumer((stream) => stream.on("data", (line) => consoleLogger(LogEvent.info(String(line)))).on("err", (line) => consoleLogger(LogEvent.error(String(line)))).on("end", () => consoleLogger(LogEvent.info("Stream closed"))));
|
|
281
|
+
return startedContainer;
|
|
282
|
+
}, { lockId: "SharedEventStoreDBTestContainer" });
|
|
283
|
+
const getSharedTestEventStoreDBClient = async () => {
|
|
284
|
+
return (await getSharedEventStoreDBTestContainer()).getClient();
|
|
295
285
|
};
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
} catch {
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
},
|
|
308
|
-
{ lockId: "SharedEventStoreDBTestContainer" }
|
|
309
|
-
);
|
|
286
|
+
const releaseSharedEventStoreDBTestContainer = () => lock.withAcquire(async () => {
|
|
287
|
+
const containerToStop = startedContainer;
|
|
288
|
+
if (containerToStop && --startedCount === 0) try {
|
|
289
|
+
startedContainer = null;
|
|
290
|
+
container = null;
|
|
291
|
+
await containerToStop.stop();
|
|
292
|
+
} catch {}
|
|
293
|
+
}, { lockId: "SharedEventStoreDBTestContainer" });
|
|
310
294
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
return EventStoreDBClient2.connectionString(connectionString);
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region src/eventStore/index.ts
|
|
297
|
+
let esdbContainer;
|
|
298
|
+
const getEventStoreDBTestClient = async (useTestContainers = false) => {
|
|
299
|
+
let connectionString;
|
|
300
|
+
if (useTestContainers) {
|
|
301
|
+
if (!esdbContainer) esdbContainer = await new EventStoreDBContainer().start();
|
|
302
|
+
connectionString = esdbContainer.getConnectionString();
|
|
303
|
+
} else connectionString = "esdb://localhost:2113?tls=false";
|
|
304
|
+
return EventStoreDBClient.connectionString(connectionString);
|
|
323
305
|
};
|
|
324
306
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
307
|
+
//#endregion
|
|
308
|
+
//#region src/mongodb/mongoDBContainer.ts
|
|
309
|
+
const getMongoDBContainer = (options = { version: "6.0.1" }) => {
|
|
310
|
+
return new MongoDBContainer(`mongo:${options.version}`);
|
|
329
311
|
};
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
return container2.start();
|
|
312
|
+
const getMongoDBStartedContainer = async (options = { version: "6.0.1" }) => {
|
|
313
|
+
return getMongoDBContainer(options).start();
|
|
333
314
|
};
|
|
334
315
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region src/postgresql/postgreSQLContainer.ts
|
|
318
|
+
const getPostgreSQLContainer = (options = { version: "18.1" }) => {
|
|
319
|
+
return new PostgreSqlContainer(`postgres:${options.version}`);
|
|
339
320
|
};
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
return container2.start();
|
|
343
|
-
};
|
|
344
|
-
export {
|
|
345
|
-
EVENTSTOREDB_ARM64_IMAGE_TAG,
|
|
346
|
-
EVENTSTOREDB_DEFAULT_IMAGE,
|
|
347
|
-
EVENTSTOREDB_IMAGE_NAME,
|
|
348
|
-
EVENTSTOREDB_IMAGE_TAG,
|
|
349
|
-
EVENTSTOREDB_PORT,
|
|
350
|
-
EventStoreDBContainer,
|
|
351
|
-
StartedEventStoreDBContainer,
|
|
352
|
-
defaultEventStoreDBContainerOptions,
|
|
353
|
-
getEventStoreDBTestClient,
|
|
354
|
-
getMongoDBContainer,
|
|
355
|
-
getMongoDBStartedContainer,
|
|
356
|
-
getPostgreSQLContainer,
|
|
357
|
-
getPostgreSQLStartedContainer,
|
|
358
|
-
getSharedEventStoreDBTestContainer,
|
|
359
|
-
getSharedTestEventStoreDBClient,
|
|
360
|
-
releaseSharedEventStoreDBTestContainer
|
|
321
|
+
const getPostgreSQLStartedContainer = async (options = { version: "18.1" }) => {
|
|
322
|
+
return getPostgreSQLContainer(options).start();
|
|
361
323
|
};
|
|
324
|
+
|
|
325
|
+
//#endregion
|
|
326
|
+
export { EVENTSTOREDB_ARM64_IMAGE_TAG, EVENTSTOREDB_DEFAULT_IMAGE, EVENTSTOREDB_IMAGE_NAME, EVENTSTOREDB_IMAGE_TAG, EVENTSTOREDB_PORT, EventStoreDBContainer, StartedEventStoreDBContainer, defaultEventStoreDBContainerOptions, getEventStoreDBTestClient, getMongoDBContainer, getMongoDBStartedContainer, getPostgreSQLContainer, getPostgreSQLStartedContainer, getSharedEventStoreDBTestContainer, getSharedTestEventStoreDBClient, releaseSharedEventStoreDBTestContainer };
|
|
362
327
|
//# sourceMappingURL=index.js.map
|