@event-driven-io/emmett-expressjs 0.43.0-beta.13 → 0.43.0-beta.15
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/dist/index.cjs +316 -1236
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -59
- package/dist/index.d.ts +69 -59
- package/dist/index.js +227 -1216
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1,1240 +1,320 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
if (!found) return false;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return true;
|
|
176
|
-
};
|
|
177
|
-
var compareArrayBuffers = (left, right) => {
|
|
178
|
-
if (left.byteLength !== right.byteLength) return false;
|
|
179
|
-
const leftView = new Uint8Array(left);
|
|
180
|
-
const rightView = new Uint8Array(right);
|
|
181
|
-
for (let i = 0; i < leftView.length; i++) {
|
|
182
|
-
if (leftView[i] !== rightView[i]) return false;
|
|
183
|
-
}
|
|
184
|
-
return true;
|
|
185
|
-
};
|
|
186
|
-
var compareTypedArrays = (left, right) => {
|
|
187
|
-
if (left.constructor !== right.constructor) return false;
|
|
188
|
-
if (left.byteLength !== right.byteLength) return false;
|
|
189
|
-
const leftArray = new Uint8Array(
|
|
190
|
-
left.buffer,
|
|
191
|
-
left.byteOffset,
|
|
192
|
-
left.byteLength
|
|
193
|
-
);
|
|
194
|
-
const rightArray = new Uint8Array(
|
|
195
|
-
right.buffer,
|
|
196
|
-
right.byteOffset,
|
|
197
|
-
right.byteLength
|
|
198
|
-
);
|
|
199
|
-
for (let i = 0; i < leftArray.length; i++) {
|
|
200
|
-
if (leftArray[i] !== rightArray[i]) return false;
|
|
201
|
-
}
|
|
202
|
-
return true;
|
|
203
|
-
};
|
|
204
|
-
var compareObjects = (left, right) => {
|
|
205
|
-
const keys1 = Object.keys(left);
|
|
206
|
-
const keys2 = Object.keys(right);
|
|
207
|
-
if (keys1.length !== keys2.length) {
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
for (const key of keys1) {
|
|
211
|
-
if (left[key] instanceof Function && right[key] instanceof Function) {
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
const isEqual = deepEquals(left[key], right[key]);
|
|
215
|
-
if (!isEqual) {
|
|
216
|
-
return false;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
return true;
|
|
220
|
-
};
|
|
221
|
-
var getType = (value) => {
|
|
222
|
-
if (value === null) return "null";
|
|
223
|
-
if (value === void 0) return "undefined";
|
|
224
|
-
const primitiveType = typeof value;
|
|
225
|
-
if (primitiveType !== "object") return primitiveType;
|
|
226
|
-
if (Array.isArray(value)) return "array";
|
|
227
|
-
if (value instanceof Boolean) return "boxed-boolean";
|
|
228
|
-
if (value instanceof Number) return "boxed-number";
|
|
229
|
-
if (value instanceof String) return "boxed-string";
|
|
230
|
-
if (value instanceof Date) return "date";
|
|
231
|
-
if (value instanceof RegExp) return "regexp";
|
|
232
|
-
if (value instanceof Error) return "error";
|
|
233
|
-
if (value instanceof Map) return "map";
|
|
234
|
-
if (value instanceof Set) return "set";
|
|
235
|
-
if (value instanceof ArrayBuffer) return "arraybuffer";
|
|
236
|
-
if (value instanceof DataView) return "dataview";
|
|
237
|
-
if (value instanceof WeakMap) return "weakmap";
|
|
238
|
-
if (value instanceof WeakSet) return "weakset";
|
|
239
|
-
if (ArrayBuffer.isView(value)) return "typedarray";
|
|
240
|
-
return "object";
|
|
241
|
-
};
|
|
242
|
-
var deepEquals = (left, right) => {
|
|
243
|
-
if (left === right) return true;
|
|
244
|
-
if (isEquatable(left)) {
|
|
245
|
-
return left.equals(right);
|
|
246
|
-
}
|
|
247
|
-
const leftType = getType(left);
|
|
248
|
-
const rightType = getType(right);
|
|
249
|
-
if (leftType !== rightType) return false;
|
|
250
|
-
switch (leftType) {
|
|
251
|
-
case "null":
|
|
252
|
-
case "undefined":
|
|
253
|
-
case "boolean":
|
|
254
|
-
case "number":
|
|
255
|
-
case "bigint":
|
|
256
|
-
case "string":
|
|
257
|
-
case "symbol":
|
|
258
|
-
case "function":
|
|
259
|
-
return left === right;
|
|
260
|
-
case "array":
|
|
261
|
-
return compareArrays(left, right);
|
|
262
|
-
case "date":
|
|
263
|
-
return compareDates(left, right);
|
|
264
|
-
case "regexp":
|
|
265
|
-
return compareRegExps(left, right);
|
|
266
|
-
case "error":
|
|
267
|
-
return compareErrors(left, right);
|
|
268
|
-
case "map":
|
|
269
|
-
return compareMaps(
|
|
270
|
-
left,
|
|
271
|
-
right
|
|
272
|
-
);
|
|
273
|
-
case "set":
|
|
274
|
-
return compareSets(left, right);
|
|
275
|
-
case "arraybuffer":
|
|
276
|
-
return compareArrayBuffers(left, right);
|
|
277
|
-
case "dataview":
|
|
278
|
-
case "weakmap":
|
|
279
|
-
case "weakset":
|
|
280
|
-
return false;
|
|
281
|
-
case "typedarray":
|
|
282
|
-
return compareTypedArrays(
|
|
283
|
-
left,
|
|
284
|
-
right
|
|
285
|
-
);
|
|
286
|
-
case "boxed-boolean":
|
|
287
|
-
return left.valueOf() === right.valueOf();
|
|
288
|
-
case "boxed-number":
|
|
289
|
-
return left.valueOf() === right.valueOf();
|
|
290
|
-
case "boxed-string":
|
|
291
|
-
return left.valueOf() === right.valueOf();
|
|
292
|
-
case "object":
|
|
293
|
-
return compareObjects(
|
|
294
|
-
left,
|
|
295
|
-
right
|
|
296
|
-
);
|
|
297
|
-
default:
|
|
298
|
-
return false;
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
|
-
var isEquatable = (left) => {
|
|
302
|
-
return left !== null && left !== void 0 && typeof left === "object" && "equals" in left && typeof left["equals"] === "function";
|
|
303
|
-
};
|
|
304
|
-
var toNormalizedString = (value) => value.toString().padStart(19, "0");
|
|
305
|
-
var bigInt = {
|
|
306
|
-
toNormalizedString
|
|
307
|
-
};
|
|
308
|
-
var bigIntReplacer = (_key, value) => {
|
|
309
|
-
return typeof value === "bigint" ? value.toString() : value;
|
|
310
|
-
};
|
|
311
|
-
var dateReplacer = (_key, value) => {
|
|
312
|
-
return value instanceof Date ? value.toISOString() : value;
|
|
313
|
-
};
|
|
314
|
-
var isFirstLetterNumeric = (str) => {
|
|
315
|
-
const c = str.charCodeAt(0);
|
|
316
|
-
return c >= 48 && c <= 57;
|
|
317
|
-
};
|
|
318
|
-
var isFirstLetterNumericOrMinus = (str) => {
|
|
319
|
-
const c = str.charCodeAt(0);
|
|
320
|
-
return c >= 48 && c <= 57 || c === 45;
|
|
321
|
-
};
|
|
322
|
-
var bigIntReviver = (_key, value, context) => {
|
|
323
|
-
if (typeof value === "number" && Number.isInteger(value) && !Number.isSafeInteger(value)) {
|
|
324
|
-
try {
|
|
325
|
-
return BigInt(_nullishCoalesce(_optionalChain([context, 'optionalAccess', _10 => _10.source]), () => ( value.toString())));
|
|
326
|
-
} catch (e2) {
|
|
327
|
-
return value;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
if (typeof value === "string" && value.length > 15) {
|
|
331
|
-
if (isFirstLetterNumericOrMinus(value)) {
|
|
332
|
-
const num = Number(value);
|
|
333
|
-
if (Number.isFinite(num) && !Number.isSafeInteger(num)) {
|
|
334
|
-
try {
|
|
335
|
-
return BigInt(value);
|
|
336
|
-
} catch (e3) {
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
return value;
|
|
342
|
-
};
|
|
343
|
-
var dateReviver = (_key, value) => {
|
|
344
|
-
if (typeof value === "string" && value.length === 24 && isFirstLetterNumeric(value) && value[10] === "T" && value[23] === "Z") {
|
|
345
|
-
const date = new Date(value);
|
|
346
|
-
if (!isNaN(date.getTime())) {
|
|
347
|
-
return date;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
return value;
|
|
351
|
-
};
|
|
352
|
-
var composeJSONReplacers = (...replacers) => {
|
|
353
|
-
const filteredReplacers = replacers.filter((r) => r !== void 0);
|
|
354
|
-
if (filteredReplacers.length === 0) return void 0;
|
|
355
|
-
return (key, value) => (
|
|
356
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
357
|
-
filteredReplacers.reduce(
|
|
358
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
359
|
-
(accValue, replacer) => replacer(key, accValue),
|
|
360
|
-
value
|
|
361
|
-
)
|
|
362
|
-
);
|
|
363
|
-
};
|
|
364
|
-
var composeJSONRevivers = (...revivers) => {
|
|
365
|
-
const filteredRevivers = revivers.filter((r) => r !== void 0);
|
|
366
|
-
if (filteredRevivers.length === 0) return void 0;
|
|
367
|
-
return (key, value, context) => (
|
|
368
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
369
|
-
filteredRevivers.reduce(
|
|
370
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
371
|
-
(accValue, reviver) => reviver(key, accValue, context),
|
|
372
|
-
value
|
|
373
|
-
)
|
|
374
|
-
);
|
|
375
|
-
};
|
|
376
|
-
var JSONReplacer = (opts) => composeJSONReplacers(
|
|
377
|
-
_optionalChain([opts, 'optionalAccess', _11 => _11.replacer]),
|
|
378
|
-
_optionalChain([opts, 'optionalAccess', _12 => _12.failOnBigIntSerialization]) !== true ? JSONReplacers.bigInt : void 0,
|
|
379
|
-
_optionalChain([opts, 'optionalAccess', _13 => _13.useDefaultDateSerialization]) !== true ? JSONReplacers.date : void 0
|
|
380
|
-
);
|
|
381
|
-
var JSONReviver = (opts) => composeJSONRevivers(
|
|
382
|
-
_optionalChain([opts, 'optionalAccess', _14 => _14.reviver]),
|
|
383
|
-
_optionalChain([opts, 'optionalAccess', _15 => _15.parseBigInts]) === true ? JSONRevivers.bigInt : void 0,
|
|
384
|
-
_optionalChain([opts, 'optionalAccess', _16 => _16.parseDates]) === true ? JSONRevivers.date : void 0
|
|
385
|
-
);
|
|
386
|
-
var JSONReplacers = {
|
|
387
|
-
bigInt: bigIntReplacer,
|
|
388
|
-
date: dateReplacer
|
|
389
|
-
};
|
|
390
|
-
var JSONRevivers = {
|
|
391
|
-
bigInt: bigIntReviver,
|
|
392
|
-
date: dateReviver
|
|
393
|
-
};
|
|
394
|
-
var jsonSerializer = (options) => {
|
|
395
|
-
const defaultReplacer = JSONReplacer(options);
|
|
396
|
-
const defaultReviver = JSONReviver(options);
|
|
397
|
-
return {
|
|
398
|
-
serialize: (object, serializerOptions) => JSON.stringify(
|
|
399
|
-
object,
|
|
400
|
-
serializerOptions ? JSONReplacer(serializerOptions) : defaultReplacer
|
|
401
|
-
),
|
|
402
|
-
deserialize: (payload, deserializerOptions) => JSON.parse(
|
|
403
|
-
payload,
|
|
404
|
-
deserializerOptions ? JSONReviver(deserializerOptions) : defaultReviver
|
|
405
|
-
)
|
|
406
|
-
};
|
|
407
|
-
};
|
|
408
|
-
var JSONSerializer = Object.assign(jsonSerializer(), {
|
|
409
|
-
from: (options) => _nullishCoalesce(_optionalChain([options, 'optionalAccess', _17 => _17.serialization, 'optionalAccess', _18 => _18.serializer]), () => ( (_optionalChain([options, 'optionalAccess', _19 => _19.serialization, 'optionalAccess', _20 => _20.options]) ? jsonSerializer(_optionalChain([options, 'optionalAccess', _21 => _21.serialization, 'optionalAccess', _22 => _22.options])) : JSONSerializer)))
|
|
410
|
-
});
|
|
411
|
-
var textEncoder = new TextEncoder();
|
|
412
|
-
var isGeneralExpectedDocumentVersion = (version) => {
|
|
413
|
-
return version === "DOCUMENT_DOES_NOT_EXIST" || version === "DOCUMENT_EXISTS" || version === "NO_CONCURRENCY_CHECK";
|
|
414
|
-
};
|
|
415
|
-
var expectedVersionValue = (version) => version === void 0 || isGeneralExpectedDocumentVersion(version) ? null : version;
|
|
416
|
-
var operationResult = (result, options) => {
|
|
417
|
-
const operationResult2 = {
|
|
418
|
-
...result,
|
|
419
|
-
acknowledged: true,
|
|
420
|
-
successful: result.successful,
|
|
421
|
-
assertSuccessful: (errorMessage) => {
|
|
422
|
-
const { successful } = result;
|
|
423
|
-
const { operationName, collectionName } = options;
|
|
424
|
-
if (!successful)
|
|
425
|
-
throw new ConcurrencyInMemoryDatabaseError(
|
|
426
|
-
_nullishCoalesce(errorMessage, () => ( `${operationName} on ${collectionName} failed. Expected document state does not match current one! Result: ${JSONSerializer.serialize(result)}!`))
|
|
427
|
-
);
|
|
428
|
-
}
|
|
429
|
-
};
|
|
430
|
-
if (_optionalChain([options, 'access', _23 => _23.errors, 'optionalAccess', _24 => _24.throwOnOperationFailures]))
|
|
431
|
-
operationResult2.assertSuccessful();
|
|
432
|
-
return operationResult2;
|
|
433
|
-
};
|
|
434
|
-
var getInMemoryDatabase = () => {
|
|
435
|
-
const storage = /* @__PURE__ */ new Map();
|
|
436
|
-
return {
|
|
437
|
-
collection: (collectionName, collectionOptions = {}) => {
|
|
438
|
-
const ensureCollectionCreated = () => {
|
|
439
|
-
if (!storage.has(collectionName)) storage.set(collectionName, []);
|
|
440
|
-
};
|
|
441
|
-
const errors = collectionOptions.errors;
|
|
442
|
-
const collection = {
|
|
443
|
-
collectionName,
|
|
444
|
-
insertOne: async (document) => {
|
|
445
|
-
ensureCollectionCreated();
|
|
446
|
-
const _id = _nullishCoalesce(document._id, () => ( _uuid.v7.call(void 0, )));
|
|
447
|
-
const _version = _nullishCoalesce(document._version, () => ( 1n));
|
|
448
|
-
const existing = await collection.findOne((c) => c._id === _id);
|
|
449
|
-
if (existing) {
|
|
450
|
-
return operationResult(
|
|
451
|
-
{
|
|
452
|
-
successful: false,
|
|
453
|
-
insertedId: null,
|
|
454
|
-
nextExpectedVersion: _version
|
|
455
|
-
},
|
|
456
|
-
{ operationName: "insertOne", collectionName, errors }
|
|
457
|
-
);
|
|
458
|
-
}
|
|
459
|
-
const documentsInCollection = storage.get(collectionName);
|
|
460
|
-
const newDocument = { ...document, _id, _version };
|
|
461
|
-
const newCollection = [...documentsInCollection, newDocument];
|
|
462
|
-
storage.set(collectionName, newCollection);
|
|
463
|
-
return operationResult(
|
|
464
|
-
{
|
|
465
|
-
successful: true,
|
|
466
|
-
insertedId: _id,
|
|
467
|
-
nextExpectedVersion: _version
|
|
468
|
-
},
|
|
469
|
-
{ operationName: "insertOne", collectionName, errors }
|
|
470
|
-
);
|
|
471
|
-
},
|
|
472
|
-
findOne: (predicate) => {
|
|
473
|
-
ensureCollectionCreated();
|
|
474
|
-
const documentsInCollection = storage.get(collectionName);
|
|
475
|
-
const filteredDocuments = predicate ? _optionalChain([documentsInCollection, 'optionalAccess', _25 => _25.filter, 'call', _26 => _26((doc) => predicate(doc))]) : documentsInCollection;
|
|
476
|
-
const firstOne = _nullishCoalesce(_optionalChain([filteredDocuments, 'optionalAccess', _27 => _27[0]]), () => ( null));
|
|
477
|
-
return Promise.resolve(firstOne);
|
|
478
|
-
},
|
|
479
|
-
find: (predicate) => {
|
|
480
|
-
ensureCollectionCreated();
|
|
481
|
-
const documentsInCollection = storage.get(collectionName);
|
|
482
|
-
const filteredDocuments = predicate ? _optionalChain([documentsInCollection, 'optionalAccess', _28 => _28.filter, 'call', _29 => _29((doc) => predicate(doc))]) : documentsInCollection;
|
|
483
|
-
return Promise.resolve(filteredDocuments);
|
|
484
|
-
},
|
|
485
|
-
deleteOne: (predicate) => {
|
|
486
|
-
ensureCollectionCreated();
|
|
487
|
-
const documentsInCollection = storage.get(collectionName);
|
|
488
|
-
if (predicate) {
|
|
489
|
-
const foundIndex = documentsInCollection.findIndex(
|
|
490
|
-
(doc) => predicate(doc)
|
|
491
|
-
);
|
|
492
|
-
if (foundIndex === -1) {
|
|
493
|
-
return Promise.resolve(
|
|
494
|
-
operationResult(
|
|
495
|
-
{
|
|
496
|
-
successful: false,
|
|
497
|
-
matchedCount: 0,
|
|
498
|
-
deletedCount: 0
|
|
499
|
-
},
|
|
500
|
-
{ operationName: "deleteOne", collectionName, errors }
|
|
501
|
-
)
|
|
502
|
-
);
|
|
503
|
-
} else {
|
|
504
|
-
const newCollection2 = documentsInCollection.toSpliced(
|
|
505
|
-
foundIndex,
|
|
506
|
-
1
|
|
507
|
-
);
|
|
508
|
-
storage.set(collectionName, newCollection2);
|
|
509
|
-
return Promise.resolve(
|
|
510
|
-
operationResult(
|
|
511
|
-
{
|
|
512
|
-
successful: true,
|
|
513
|
-
matchedCount: 1,
|
|
514
|
-
deletedCount: 1
|
|
515
|
-
},
|
|
516
|
-
{ operationName: "deleteOne", collectionName, errors }
|
|
517
|
-
)
|
|
518
|
-
);
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
const newCollection = documentsInCollection.slice(1);
|
|
522
|
-
storage.set(collectionName, newCollection);
|
|
523
|
-
return Promise.resolve(
|
|
524
|
-
operationResult(
|
|
525
|
-
{
|
|
526
|
-
successful: true,
|
|
527
|
-
matchedCount: 1,
|
|
528
|
-
deletedCount: 1
|
|
529
|
-
},
|
|
530
|
-
{ operationName: "deleteOne", collectionName, errors }
|
|
531
|
-
)
|
|
532
|
-
);
|
|
533
|
-
},
|
|
534
|
-
replaceOne: (predicate, document, options) => {
|
|
535
|
-
ensureCollectionCreated();
|
|
536
|
-
const documentsInCollection = storage.get(collectionName);
|
|
537
|
-
const firstIndex = documentsInCollection.findIndex(
|
|
538
|
-
(doc) => predicate(doc)
|
|
539
|
-
);
|
|
540
|
-
if (firstIndex === void 0 || firstIndex === -1) {
|
|
541
|
-
return Promise.resolve(
|
|
542
|
-
operationResult(
|
|
543
|
-
{
|
|
544
|
-
successful: false,
|
|
545
|
-
matchedCount: 0,
|
|
546
|
-
modifiedCount: 0,
|
|
547
|
-
nextExpectedVersion: 0n
|
|
548
|
-
},
|
|
549
|
-
{ operationName: "replaceOne", collectionName, errors }
|
|
550
|
-
)
|
|
551
|
-
);
|
|
552
|
-
}
|
|
553
|
-
const existing = documentsInCollection[firstIndex];
|
|
554
|
-
if (typeof _optionalChain([options, 'optionalAccess', _30 => _30.expectedVersion]) === "bigint" && existing._version !== options.expectedVersion) {
|
|
555
|
-
return Promise.resolve(
|
|
556
|
-
operationResult(
|
|
557
|
-
{
|
|
558
|
-
successful: false,
|
|
559
|
-
matchedCount: 1,
|
|
560
|
-
modifiedCount: 0,
|
|
561
|
-
nextExpectedVersion: existing._version
|
|
562
|
-
},
|
|
563
|
-
{ operationName: "replaceOne", collectionName, errors }
|
|
564
|
-
)
|
|
565
|
-
);
|
|
566
|
-
}
|
|
567
|
-
const newVersion = existing._version + 1n;
|
|
568
|
-
const newCollection = documentsInCollection.with(firstIndex, {
|
|
569
|
-
_id: existing._id,
|
|
570
|
-
...document,
|
|
571
|
-
_version: newVersion
|
|
572
|
-
});
|
|
573
|
-
storage.set(collectionName, newCollection);
|
|
574
|
-
return Promise.resolve(
|
|
575
|
-
operationResult(
|
|
576
|
-
{
|
|
577
|
-
successful: true,
|
|
578
|
-
modifiedCount: 1,
|
|
579
|
-
matchedCount: firstIndex,
|
|
580
|
-
nextExpectedVersion: newVersion
|
|
581
|
-
},
|
|
582
|
-
{ operationName: "replaceOne", collectionName, errors }
|
|
583
|
-
)
|
|
584
|
-
);
|
|
585
|
-
},
|
|
586
|
-
handle: async (id, handle, options) => {
|
|
587
|
-
const { expectedVersion: version, ...operationOptions } = _nullishCoalesce(options, () => ( {}));
|
|
588
|
-
ensureCollectionCreated();
|
|
589
|
-
const existing = await collection.findOne(({ _id }) => _id === id);
|
|
590
|
-
const expectedVersion = expectedVersionValue(version);
|
|
591
|
-
if (existing == null && version === "DOCUMENT_EXISTS" || existing == null && expectedVersion != null || existing != null && version === "DOCUMENT_DOES_NOT_EXIST" || existing != null && expectedVersion !== null && existing._version !== expectedVersion) {
|
|
592
|
-
return operationResult(
|
|
593
|
-
{
|
|
594
|
-
successful: false,
|
|
595
|
-
document: existing
|
|
596
|
-
},
|
|
597
|
-
{ operationName: "handle", collectionName, errors }
|
|
598
|
-
);
|
|
599
|
-
}
|
|
600
|
-
const result = handle(existing !== null ? { ...existing } : null);
|
|
601
|
-
if (deepEquals(existing, result))
|
|
602
|
-
return operationResult(
|
|
603
|
-
{
|
|
604
|
-
successful: true,
|
|
605
|
-
document: existing
|
|
606
|
-
},
|
|
607
|
-
{ operationName: "handle", collectionName, errors }
|
|
608
|
-
);
|
|
609
|
-
if (!existing && result) {
|
|
610
|
-
const newDoc = { ...result, _id: id };
|
|
611
|
-
const insertResult = await collection.insertOne({
|
|
612
|
-
...newDoc,
|
|
613
|
-
_id: id
|
|
614
|
-
});
|
|
615
|
-
return {
|
|
616
|
-
...insertResult,
|
|
617
|
-
document: {
|
|
618
|
-
...newDoc,
|
|
619
|
-
_version: insertResult.nextExpectedVersion
|
|
620
|
-
}
|
|
621
|
-
};
|
|
622
|
-
}
|
|
623
|
-
if (existing && !result) {
|
|
624
|
-
const deleteResult = await collection.deleteOne(
|
|
625
|
-
({ _id }) => id === _id
|
|
626
|
-
);
|
|
627
|
-
return { ...deleteResult, document: null };
|
|
628
|
-
}
|
|
629
|
-
if (existing && result) {
|
|
630
|
-
const replaceResult = await collection.replaceOne(
|
|
631
|
-
({ _id }) => id === _id,
|
|
632
|
-
result,
|
|
633
|
-
{
|
|
634
|
-
...operationOptions,
|
|
635
|
-
expectedVersion: _nullishCoalesce(expectedVersion, () => ( "DOCUMENT_EXISTS"))
|
|
636
|
-
}
|
|
637
|
-
);
|
|
638
|
-
return {
|
|
639
|
-
...replaceResult,
|
|
640
|
-
document: {
|
|
641
|
-
...result,
|
|
642
|
-
_version: replaceResult.nextExpectedVersion
|
|
643
|
-
}
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
return operationResult(
|
|
647
|
-
{
|
|
648
|
-
successful: true,
|
|
649
|
-
document: existing
|
|
650
|
-
},
|
|
651
|
-
{ operationName: "handle", collectionName, errors }
|
|
652
|
-
);
|
|
653
|
-
}
|
|
654
|
-
};
|
|
655
|
-
return collection;
|
|
656
|
-
}
|
|
657
|
-
};
|
|
658
|
-
};
|
|
659
|
-
var bigIntProcessorCheckpoint = (value) => bigInt.toNormalizedString(value);
|
|
660
|
-
var handleInMemoryProjections = async (options) => {
|
|
661
|
-
const { projections: projections2, events, database, eventStore } = options;
|
|
662
|
-
const eventTypes = events.map((e) => e.type);
|
|
663
|
-
const relevantProjections = projections2.filter(
|
|
664
|
-
(p) => p.canHandle.some((type) => eventTypes.includes(type))
|
|
665
|
-
);
|
|
666
|
-
for (const projection2 of relevantProjections) {
|
|
667
|
-
await projection2.handle(events, {
|
|
668
|
-
eventStore,
|
|
669
|
-
database
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
};
|
|
673
|
-
var AssertionError = class extends Error {
|
|
674
|
-
constructor(message2) {
|
|
675
|
-
super(message2);
|
|
676
|
-
}
|
|
677
|
-
};
|
|
678
|
-
var isSubset = (superObj, subObj) => {
|
|
679
|
-
const sup = superObj;
|
|
680
|
-
const sub = subObj;
|
|
681
|
-
assertOk(sup);
|
|
682
|
-
assertOk(sub);
|
|
683
|
-
return Object.keys(sub).every((ele) => {
|
|
684
|
-
if (sub[ele] !== null && typeof sub[ele] == "object") {
|
|
685
|
-
return isSubset(sup[ele], sub[ele]);
|
|
686
|
-
}
|
|
687
|
-
return sub[ele] === sup[ele];
|
|
688
|
-
});
|
|
689
|
-
};
|
|
690
|
-
var assertFails = (message2) => {
|
|
691
|
-
throw new AssertionError(_nullishCoalesce(message2, () => ( "That should not ever happened, right?")));
|
|
692
|
-
};
|
|
693
|
-
var assertMatches = (actual, expected, message2) => {
|
|
694
|
-
if (!isSubset(actual, expected))
|
|
695
|
-
throw new AssertionError(
|
|
696
|
-
_nullishCoalesce(message2, () => ( `subObj:
|
|
697
|
-
${JSONSerializer.serialize(expected)}
|
|
698
|
-
is not subset of
|
|
699
|
-
${JSONSerializer.serialize(actual)}`))
|
|
700
|
-
);
|
|
701
|
-
};
|
|
702
|
-
function assertOk(obj, message2) {
|
|
703
|
-
if (!obj) throw new AssertionError(_nullishCoalesce(message2, () => ( `Condition is not truthy`)));
|
|
704
|
-
}
|
|
705
|
-
function assertEqual(expected, actual, message2) {
|
|
706
|
-
if (expected !== actual)
|
|
707
|
-
throw new AssertionError(
|
|
708
|
-
`${_nullishCoalesce(message2, () => ( "Objects are not equal"))}:
|
|
709
|
-
Expected: ${JSONSerializer.serialize(expected)}
|
|
710
|
-
Actual: ${JSONSerializer.serialize(actual)}`
|
|
711
|
-
);
|
|
712
|
-
}
|
|
713
|
-
var WrapEventStore = (eventStore) => {
|
|
714
|
-
const appendedEvents = /* @__PURE__ */ new Map();
|
|
715
|
-
const wrapped = {
|
|
716
|
-
...eventStore,
|
|
717
|
-
aggregateStream(streamName, options) {
|
|
718
|
-
return eventStore.aggregateStream(streamName, options);
|
|
719
|
-
},
|
|
720
|
-
async readStream(streamName, options) {
|
|
721
|
-
return await eventStore.readStream(
|
|
722
|
-
streamName,
|
|
723
|
-
options
|
|
724
|
-
);
|
|
725
|
-
},
|
|
726
|
-
appendToStream: async (streamName, events, options) => {
|
|
727
|
-
const result = await eventStore.appendToStream(
|
|
728
|
-
streamName,
|
|
729
|
-
events,
|
|
730
|
-
options
|
|
731
|
-
);
|
|
732
|
-
const currentStream = _nullishCoalesce(appendedEvents.get(streamName), () => ( [streamName, []]));
|
|
733
|
-
appendedEvents.set(streamName, [
|
|
734
|
-
streamName,
|
|
735
|
-
[...currentStream[1], ...events]
|
|
736
|
-
]);
|
|
737
|
-
return result;
|
|
738
|
-
},
|
|
739
|
-
appendedEvents,
|
|
740
|
-
setup: async (streamName, events) => {
|
|
741
|
-
return eventStore.appendToStream(streamName, events);
|
|
742
|
-
}
|
|
743
|
-
// streamEvents: (): ReadableStream<
|
|
744
|
-
// // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
|
|
745
|
-
// ReadEvent<Event, ReadEventMetadataType> | GlobalSubscriptionEvent
|
|
746
|
-
// > => {
|
|
747
|
-
// return eventStore.streamEvents();
|
|
748
|
-
// },
|
|
749
|
-
};
|
|
750
|
-
return wrapped;
|
|
751
|
-
};
|
|
752
|
-
var downcastRecordedMessage = (recordedMessage, options) => {
|
|
753
|
-
if (!_optionalChain([options, 'optionalAccess', _31 => _31.downcast]))
|
|
754
|
-
return recordedMessage;
|
|
755
|
-
const downcasted = options.downcast(
|
|
756
|
-
recordedMessage
|
|
757
|
-
);
|
|
758
|
-
return {
|
|
759
|
-
...recordedMessage,
|
|
760
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
761
|
-
data: downcasted.data,
|
|
762
|
-
..."metadata" in recordedMessage || "metadata" in downcasted ? {
|
|
763
|
-
metadata: {
|
|
764
|
-
..."metadata" in recordedMessage ? recordedMessage.metadata : {},
|
|
765
|
-
..."metadata" in downcasted ? downcasted.metadata : {}
|
|
766
|
-
}
|
|
767
|
-
} : {}
|
|
768
|
-
};
|
|
769
|
-
};
|
|
770
|
-
var downcastRecordedMessages = (recordedMessages, options) => {
|
|
771
|
-
if (!_optionalChain([options, 'optionalAccess', _32 => _32.downcast]))
|
|
772
|
-
return recordedMessages;
|
|
773
|
-
return recordedMessages.map(
|
|
774
|
-
(recordedMessage) => downcastRecordedMessage(recordedMessage, options)
|
|
775
|
-
);
|
|
776
|
-
};
|
|
777
|
-
var upcastRecordedMessage = (recordedMessage, options) => {
|
|
778
|
-
if (!_optionalChain([options, 'optionalAccess', _33 => _33.upcast]))
|
|
779
|
-
return recordedMessage;
|
|
780
|
-
const upcasted = options.upcast(
|
|
781
|
-
recordedMessage
|
|
782
|
-
);
|
|
783
|
-
return {
|
|
784
|
-
...recordedMessage,
|
|
785
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
786
|
-
data: upcasted.data,
|
|
787
|
-
..."metadata" in recordedMessage || "metadata" in upcasted ? {
|
|
788
|
-
metadata: {
|
|
789
|
-
..."metadata" in recordedMessage ? recordedMessage.metadata : {},
|
|
790
|
-
..."metadata" in upcasted ? upcasted.metadata : {}
|
|
791
|
-
}
|
|
792
|
-
} : {}
|
|
793
|
-
};
|
|
794
|
-
};
|
|
795
|
-
var upcastRecordedMessages = (recordedMessages, options) => {
|
|
796
|
-
if (!_optionalChain([options, 'optionalAccess', _34 => _34.upcast]))
|
|
797
|
-
return recordedMessages;
|
|
798
|
-
return recordedMessages.map(
|
|
799
|
-
(recordedMessage) => upcastRecordedMessage(recordedMessage, options)
|
|
800
|
-
);
|
|
801
|
-
};
|
|
802
|
-
var InMemoryEventStoreDefaultStreamVersion = 0n;
|
|
803
|
-
var getInMemoryEventStore = (eventStoreOptions) => {
|
|
804
|
-
const streams = /* @__PURE__ */ new Map();
|
|
805
|
-
const getAllEventsCount = () => {
|
|
806
|
-
return Array.from(streams.values()).map((s) => s.length).reduce((p, c) => p + c, 0);
|
|
807
|
-
};
|
|
808
|
-
const database = _optionalChain([eventStoreOptions, 'optionalAccess', _35 => _35.database]) || getInMemoryDatabase();
|
|
809
|
-
const inlineProjections2 = (_nullishCoalesce(_optionalChain([eventStoreOptions, 'optionalAccess', _36 => _36.projections]), () => ( []))).filter(({ type }) => type === "inline").map(({ projection: projection2 }) => projection2);
|
|
810
|
-
const eventStore = {
|
|
811
|
-
database,
|
|
812
|
-
async aggregateStream(streamName, options) {
|
|
813
|
-
const { evolve, initialState, read } = options;
|
|
814
|
-
const result = await this.readStream(
|
|
815
|
-
streamName,
|
|
816
|
-
read
|
|
817
|
-
);
|
|
818
|
-
const events = _nullishCoalesce(_optionalChain([result, 'optionalAccess', _37 => _37.events]), () => ( []));
|
|
819
|
-
const state = events.reduce((s, e) => evolve(s, e), initialState());
|
|
820
|
-
return {
|
|
821
|
-
currentStreamVersion: BigInt(events.length),
|
|
822
|
-
state,
|
|
823
|
-
streamExists: result.streamExists
|
|
824
|
-
};
|
|
825
|
-
},
|
|
826
|
-
readStream: (streamName, readOptions) => {
|
|
827
|
-
const events = streams.get(streamName);
|
|
828
|
-
const currentStreamVersion = events ? BigInt(events.length) : InMemoryEventStoreDefaultStreamVersion;
|
|
829
|
-
assertExpectedVersionMatchesCurrent(
|
|
830
|
-
currentStreamVersion,
|
|
831
|
-
_optionalChain([readOptions, 'optionalAccess', _38 => _38.expectedStreamVersion]),
|
|
832
|
-
InMemoryEventStoreDefaultStreamVersion
|
|
833
|
-
);
|
|
834
|
-
const from = Number(_nullishCoalesce(_optionalChain([readOptions, 'optionalAccess', _39 => _39.from]), () => ( 0)));
|
|
835
|
-
const to = Number(
|
|
836
|
-
_nullishCoalesce(_optionalChain([readOptions, 'optionalAccess', _40 => _40.to]), () => ( (_optionalChain([readOptions, 'optionalAccess', _41 => _41.maxCount]) ? (_nullishCoalesce(readOptions.from, () => ( 0n))) + readOptions.maxCount : _nullishCoalesce(_optionalChain([events, 'optionalAccess', _42 => _42.length]), () => ( 1)))))
|
|
837
|
-
);
|
|
838
|
-
const resultEvents = events !== void 0 && events.length > 0 ? upcastRecordedMessages(
|
|
839
|
-
events.slice(from, to),
|
|
840
|
-
_optionalChain([readOptions, 'optionalAccess', _43 => _43.schema, 'optionalAccess', _44 => _44.versioning])
|
|
841
|
-
) : [];
|
|
842
|
-
const result = {
|
|
843
|
-
currentStreamVersion,
|
|
844
|
-
events: resultEvents,
|
|
845
|
-
streamExists: events !== void 0 && events.length > 0
|
|
846
|
-
};
|
|
847
|
-
return Promise.resolve(result);
|
|
848
|
-
},
|
|
849
|
-
appendToStream: async (streamName, events, options) => {
|
|
850
|
-
const currentEvents = _nullishCoalesce(streams.get(streamName), () => ( []));
|
|
851
|
-
const currentStreamVersion = currentEvents.length > 0 ? BigInt(currentEvents.length) : InMemoryEventStoreDefaultStreamVersion;
|
|
852
|
-
assertExpectedVersionMatchesCurrent(
|
|
853
|
-
currentStreamVersion,
|
|
854
|
-
_optionalChain([options, 'optionalAccess', _45 => _45.expectedStreamVersion]),
|
|
855
|
-
InMemoryEventStoreDefaultStreamVersion
|
|
856
|
-
);
|
|
857
|
-
const newEvents = events.map((event2, index) => {
|
|
858
|
-
const globalPosition = BigInt(getAllEventsCount() + index + 1);
|
|
859
|
-
const metadata = {
|
|
860
|
-
streamName,
|
|
861
|
-
messageId: _uuid.v4.call(void 0, ),
|
|
862
|
-
streamPosition: BigInt(currentEvents.length + index + 1),
|
|
863
|
-
globalPosition,
|
|
864
|
-
checkpoint: bigIntProcessorCheckpoint(globalPosition)
|
|
865
|
-
};
|
|
866
|
-
return {
|
|
867
|
-
...event2,
|
|
868
|
-
kind: _nullishCoalesce(event2.kind, () => ( "Event")),
|
|
869
|
-
metadata: {
|
|
870
|
-
..."metadata" in event2 ? _nullishCoalesce(event2.metadata, () => ( {})) : {},
|
|
871
|
-
...metadata
|
|
872
|
-
}
|
|
873
|
-
};
|
|
874
|
-
});
|
|
875
|
-
const positionOfLastEventInTheStream = BigInt(
|
|
876
|
-
newEvents.slice(-1)[0].metadata.streamPosition
|
|
877
|
-
);
|
|
878
|
-
streams.set(streamName, [
|
|
879
|
-
...currentEvents,
|
|
880
|
-
...downcastRecordedMessages(newEvents, _optionalChain([options, 'optionalAccess', _46 => _46.schema, 'optionalAccess', _47 => _47.versioning]))
|
|
881
|
-
]);
|
|
882
|
-
if (inlineProjections2.length > 0) {
|
|
883
|
-
await handleInMemoryProjections({
|
|
884
|
-
projections: inlineProjections2,
|
|
885
|
-
events: newEvents,
|
|
886
|
-
database: eventStore.database,
|
|
887
|
-
eventStore
|
|
888
|
-
});
|
|
889
|
-
}
|
|
890
|
-
const result = {
|
|
891
|
-
nextExpectedStreamVersion: positionOfLastEventInTheStream,
|
|
892
|
-
createdNewStream: currentStreamVersion === InMemoryEventStoreDefaultStreamVersion
|
|
893
|
-
};
|
|
894
|
-
await tryPublishMessagesAfterCommit(
|
|
895
|
-
newEvents,
|
|
896
|
-
_optionalChain([eventStoreOptions, 'optionalAccess', _48 => _48.hooks])
|
|
897
|
-
);
|
|
898
|
-
return result;
|
|
899
|
-
},
|
|
900
|
-
streamExists: (streamName) => {
|
|
901
|
-
const events = streams.get(streamName);
|
|
902
|
-
return Promise.resolve(events !== void 0 && events.length > 0);
|
|
903
|
-
}
|
|
904
|
-
};
|
|
905
|
-
return eventStore;
|
|
906
|
-
};
|
|
907
|
-
|
|
908
|
-
// src/middlewares/problemDetailsMiddleware.ts
|
|
909
|
-
var _httpproblemdetails = require('http-problem-details');
|
|
910
|
-
var problemDetailsMiddleware = (mapError) => (error, request, response, _next) => {
|
|
911
|
-
let problemDetails;
|
|
912
|
-
if (mapError) problemDetails = mapError(error, request);
|
|
913
|
-
problemDetails = _nullishCoalesce(problemDetails, () => ( defaultErrorToProblemDetailsMapping(error)));
|
|
914
|
-
sendProblem(response, problemDetails.status, { problem: problemDetails });
|
|
915
|
-
};
|
|
916
|
-
var defaultErrorToProblemDetailsMapping = (error) => {
|
|
917
|
-
let statusCode = 500;
|
|
918
|
-
if ("errorCode" in error && isNumber(error.errorCode) && error.errorCode >= 100 && error.errorCode < 600) {
|
|
919
|
-
statusCode = error.errorCode;
|
|
920
|
-
}
|
|
921
|
-
return new (0, _httpproblemdetails.ProblemDocument)({
|
|
922
|
-
detail: error.message,
|
|
923
|
-
status: statusCode
|
|
924
|
-
});
|
|
925
|
-
};
|
|
926
|
-
|
|
927
|
-
// src/application.ts
|
|
928
|
-
var getApplication = (options) => {
|
|
929
|
-
const app = _express2.default.call(void 0, );
|
|
930
|
-
const {
|
|
931
|
-
apis,
|
|
932
|
-
mapError,
|
|
933
|
-
enableDefaultExpressEtag,
|
|
934
|
-
disableJsonMiddleware,
|
|
935
|
-
disableUrlEncodingMiddleware,
|
|
936
|
-
disableProblemDetailsMiddleware
|
|
937
|
-
} = options;
|
|
938
|
-
const router = _express.Router.call(void 0, );
|
|
939
|
-
app.set("etag", _nullishCoalesce(enableDefaultExpressEtag, () => ( false)));
|
|
940
|
-
if (!disableJsonMiddleware) app.use(_express2.default.json());
|
|
941
|
-
if (!disableUrlEncodingMiddleware)
|
|
942
|
-
app.use(
|
|
943
|
-
_express2.default.urlencoded({
|
|
944
|
-
extended: true
|
|
945
|
-
})
|
|
946
|
-
);
|
|
947
|
-
for (const api of apis) {
|
|
948
|
-
api(router);
|
|
949
|
-
}
|
|
950
|
-
app.use(router);
|
|
951
|
-
if (!disableProblemDetailsMiddleware)
|
|
952
|
-
app.use(problemDetailsMiddleware(mapError));
|
|
953
|
-
return app;
|
|
954
|
-
};
|
|
955
|
-
var startAPI = (app, options = { port: 3e3 }) => {
|
|
956
|
-
const { port } = options;
|
|
957
|
-
const server = _http2.default.createServer(app);
|
|
958
|
-
server.on("listening", () => {
|
|
959
|
-
console.info("server up listening");
|
|
960
|
-
});
|
|
961
|
-
return server.listen(port);
|
|
962
|
-
};
|
|
963
|
-
|
|
964
|
-
// src/etag.ts
|
|
965
|
-
var HeaderNames = {
|
|
966
|
-
IF_MATCH: "if-match",
|
|
967
|
-
IF_NOT_MATCH: "if-not-match",
|
|
968
|
-
ETag: "etag"
|
|
969
|
-
};
|
|
970
|
-
var WeakETagRegex = /W\/"(-?\d+.*)"/;
|
|
971
|
-
var ETagErrors = /* @__PURE__ */ ((ETagErrors2) => {
|
|
972
|
-
ETagErrors2["WRONG_WEAK_ETAG_FORMAT"] = "WRONG_WEAK_ETAG_FORMAT";
|
|
973
|
-
ETagErrors2["MISSING_IF_MATCH_HEADER"] = "MISSING_IF_MATCH_HEADER";
|
|
974
|
-
ETagErrors2["MISSING_IF_NOT_MATCH_HEADER"] = "MISSING_IF_NOT_MATCH_HEADER";
|
|
975
|
-
return ETagErrors2;
|
|
976
|
-
})(ETagErrors || {});
|
|
977
|
-
var isWeakETag = (etag) => {
|
|
978
|
-
return WeakETagRegex.test(etag);
|
|
979
|
-
};
|
|
980
|
-
var getWeakETagValue = (etag) => {
|
|
981
|
-
const result = WeakETagRegex.exec(etag);
|
|
982
|
-
if (result === null || result.length === 0) {
|
|
983
|
-
throw new EmmettError({
|
|
984
|
-
errorCode: EmmettError.Codes.ConcurrencyError,
|
|
985
|
-
message: "WRONG_WEAK_ETAG_FORMAT" /* WRONG_WEAK_ETAG_FORMAT */
|
|
986
|
-
});
|
|
987
|
-
}
|
|
988
|
-
return result[1];
|
|
989
|
-
};
|
|
990
|
-
var toWeakETag = (value) => {
|
|
991
|
-
return `W/"${value}"`;
|
|
992
|
-
};
|
|
993
|
-
var getETagFromIfMatch = (request) => {
|
|
994
|
-
const etag = request.headers[HeaderNames.IF_MATCH];
|
|
995
|
-
if (etag === void 0) {
|
|
996
|
-
throw new EmmettError({
|
|
997
|
-
errorCode: EmmettError.Codes.ConcurrencyError,
|
|
998
|
-
message: "MISSING_IF_MATCH_HEADER" /* MISSING_IF_MATCH_HEADER */
|
|
999
|
-
});
|
|
1000
|
-
}
|
|
1001
|
-
return etag;
|
|
1002
|
-
};
|
|
1003
|
-
var getETagFromIfNotMatch = (request) => {
|
|
1004
|
-
const etag = request.headers[HeaderNames.IF_NOT_MATCH];
|
|
1005
|
-
if (etag === void 0) {
|
|
1006
|
-
throw new EmmettError({
|
|
1007
|
-
errorCode: EmmettError.Codes.ConcurrencyError,
|
|
1008
|
-
message: "MISSING_IF_NOT_MATCH_HEADER" /* MISSING_IF_NOT_MATCH_HEADER */
|
|
1009
|
-
});
|
|
1010
|
-
}
|
|
1011
|
-
return Array.isArray(etag) ? etag[0] : etag;
|
|
1012
|
-
};
|
|
1013
|
-
var setETag = (response, etag) => {
|
|
1014
|
-
response.setHeader(HeaderNames.ETag, etag);
|
|
1015
|
-
};
|
|
1016
|
-
var getETagValueFromIfMatch = (request) => {
|
|
1017
|
-
const eTagValue = getETagFromIfMatch(request);
|
|
1018
|
-
return isWeakETag(eTagValue) ? getWeakETagValue(eTagValue) : eTagValue;
|
|
1019
|
-
};
|
|
1020
|
-
|
|
1021
|
-
// src/handler.ts
|
|
1022
|
-
var on = (handle) => async (request, response, _next) => {
|
|
1023
|
-
const setResponse = await Promise.resolve(handle(request));
|
|
1024
|
-
return setResponse(response);
|
|
1025
|
-
};
|
|
1026
|
-
var OK = (options) => (response) => {
|
|
1027
|
-
send(response, 200, options);
|
|
1028
|
-
};
|
|
1029
|
-
var Created = (options) => (response) => {
|
|
1030
|
-
sendCreated(response, options);
|
|
1031
|
-
};
|
|
1032
|
-
var Accepted = (options) => (response) => {
|
|
1033
|
-
sendAccepted(response, options);
|
|
1034
|
-
};
|
|
1035
|
-
var NoContent = (options) => HttpResponse(204, options);
|
|
1036
|
-
var HttpResponse = (statusCode, options) => (response) => {
|
|
1037
|
-
send(response, statusCode, options);
|
|
1038
|
-
};
|
|
1039
|
-
var BadRequest = (options) => HttpProblem(400, options);
|
|
1040
|
-
var Forbidden = (options) => HttpProblem(403, options);
|
|
1041
|
-
var NotFound = (options) => HttpProblem(404, options);
|
|
1042
|
-
var Conflict = (options) => HttpProblem(409, options);
|
|
1043
|
-
var PreconditionFailed = (options) => HttpProblem(412, options);
|
|
1044
|
-
var HttpProblem = (statusCode, options) => (response) => {
|
|
1045
|
-
sendProblem(response, statusCode, options);
|
|
1046
|
-
};
|
|
1047
|
-
|
|
1048
|
-
// src/responses.ts
|
|
1049
|
-
|
|
1050
|
-
var DefaultHttpResponseOptions = {};
|
|
1051
|
-
var DefaultHttpProblemResponseOptions = {
|
|
1052
|
-
problemDetails: "Error occured!"
|
|
1053
|
-
};
|
|
1054
|
-
var sendCreated = (response, { eTag, ...options }) => send(response, 201, {
|
|
1055
|
-
location: "url" in options ? options.url : `${response.req.url}/${options.createdId}`,
|
|
1056
|
-
body: "createdId" in options ? { id: options.createdId, ..._nullishCoalesce(options.body, () => ( {})) } : options.body,
|
|
1057
|
-
eTag
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: ((k) => from[k]).bind(null, key),
|
|
16
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
24
|
+
value: mod,
|
|
25
|
+
enumerable: true
|
|
26
|
+
}) : target, mod));
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
require("express-async-errors");
|
|
30
|
+
let express = require("express");
|
|
31
|
+
express = __toESM(express, 1);
|
|
32
|
+
let http = require("http");
|
|
33
|
+
http = __toESM(http, 1);
|
|
34
|
+
let _event_driven_io_emmett = require("@event-driven-io/emmett");
|
|
35
|
+
let http_problem_details = require("http-problem-details");
|
|
36
|
+
let supertest = require("supertest");
|
|
37
|
+
supertest = __toESM(supertest, 1);
|
|
38
|
+
let assert = require("assert");
|
|
39
|
+
assert = __toESM(assert, 1);
|
|
40
|
+
|
|
41
|
+
//#region src/middlewares/problemDetailsMiddleware.ts
|
|
42
|
+
const problemDetailsMiddleware = (mapError) => (error, request, response, _next) => {
|
|
43
|
+
let problemDetails;
|
|
44
|
+
if (mapError) problemDetails = mapError(error, request);
|
|
45
|
+
problemDetails = problemDetails ?? defaultErrorToProblemDetailsMapping(error);
|
|
46
|
+
sendProblem(response, problemDetails.status, { problem: problemDetails });
|
|
47
|
+
};
|
|
48
|
+
const defaultErrorToProblemDetailsMapping = (error) => {
|
|
49
|
+
let statusCode = 500;
|
|
50
|
+
if ("errorCode" in error && (0, _event_driven_io_emmett.isNumber)(error.errorCode) && error.errorCode >= 100 && error.errorCode < 600) statusCode = error.errorCode;
|
|
51
|
+
return new http_problem_details.ProblemDocument({
|
|
52
|
+
detail: error.message,
|
|
53
|
+
status: statusCode
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/application.ts
|
|
59
|
+
const getApplication = (options) => {
|
|
60
|
+
const app = (0, express.default)();
|
|
61
|
+
const { apis, mapError, enableDefaultExpressEtag, disableJsonMiddleware, disableUrlEncodingMiddleware, disableProblemDetailsMiddleware } = options;
|
|
62
|
+
const router = (0, express.Router)();
|
|
63
|
+
app.set("etag", enableDefaultExpressEtag ?? false);
|
|
64
|
+
if (!disableJsonMiddleware) app.use(express.default.json());
|
|
65
|
+
if (!disableUrlEncodingMiddleware) app.use(express.default.urlencoded({ extended: true }));
|
|
66
|
+
for (const api of apis) api(router);
|
|
67
|
+
app.use(router);
|
|
68
|
+
if (!disableProblemDetailsMiddleware) app.use(problemDetailsMiddleware(mapError));
|
|
69
|
+
return app;
|
|
70
|
+
};
|
|
71
|
+
const startAPI = (app, options = { port: 3e3 }) => {
|
|
72
|
+
const { port } = options;
|
|
73
|
+
const server = http.default.createServer(app);
|
|
74
|
+
server.on("listening", () => {
|
|
75
|
+
console.info("server up listening");
|
|
76
|
+
});
|
|
77
|
+
return server.listen(port);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
//#endregion
|
|
81
|
+
//#region src/etag.ts
|
|
82
|
+
const HeaderNames = {
|
|
83
|
+
IF_MATCH: "if-match",
|
|
84
|
+
IF_NOT_MATCH: "if-not-match",
|
|
85
|
+
ETag: "etag"
|
|
86
|
+
};
|
|
87
|
+
const WeakETagRegex = /W\/"(-?\d+.*)"/;
|
|
88
|
+
let ETagErrors = /* @__PURE__ */ function(ETagErrors) {
|
|
89
|
+
ETagErrors["WRONG_WEAK_ETAG_FORMAT"] = "WRONG_WEAK_ETAG_FORMAT";
|
|
90
|
+
ETagErrors["MISSING_IF_MATCH_HEADER"] = "MISSING_IF_MATCH_HEADER";
|
|
91
|
+
ETagErrors["MISSING_IF_NOT_MATCH_HEADER"] = "MISSING_IF_NOT_MATCH_HEADER";
|
|
92
|
+
return ETagErrors;
|
|
93
|
+
}({});
|
|
94
|
+
const isWeakETag = (etag) => {
|
|
95
|
+
return WeakETagRegex.test(etag);
|
|
96
|
+
};
|
|
97
|
+
const getWeakETagValue = (etag) => {
|
|
98
|
+
const result = WeakETagRegex.exec(etag);
|
|
99
|
+
if (result === null || result.length === 0) throw new _event_driven_io_emmett.EmmettError({
|
|
100
|
+
errorCode: _event_driven_io_emmett.EmmettError.Codes.ConcurrencyError,
|
|
101
|
+
message: "WRONG_WEAK_ETAG_FORMAT"
|
|
102
|
+
});
|
|
103
|
+
return result[1];
|
|
104
|
+
};
|
|
105
|
+
const toWeakETag = (value) => {
|
|
106
|
+
return `W/"${value}"`;
|
|
107
|
+
};
|
|
108
|
+
const getETagFromIfMatch = (request) => {
|
|
109
|
+
const etag = request.headers[HeaderNames.IF_MATCH];
|
|
110
|
+
if (etag === void 0) throw new _event_driven_io_emmett.EmmettError({
|
|
111
|
+
errorCode: _event_driven_io_emmett.EmmettError.Codes.ConcurrencyError,
|
|
112
|
+
message: "MISSING_IF_MATCH_HEADER"
|
|
113
|
+
});
|
|
114
|
+
return etag;
|
|
115
|
+
};
|
|
116
|
+
const getETagFromIfNotMatch = (request) => {
|
|
117
|
+
const etag = request.headers[HeaderNames.IF_NOT_MATCH];
|
|
118
|
+
if (etag === void 0) throw new _event_driven_io_emmett.EmmettError({
|
|
119
|
+
errorCode: _event_driven_io_emmett.EmmettError.Codes.ConcurrencyError,
|
|
120
|
+
message: "MISSING_IF_NOT_MATCH_HEADER"
|
|
121
|
+
});
|
|
122
|
+
return Array.isArray(etag) ? etag[0] : etag;
|
|
123
|
+
};
|
|
124
|
+
const setETag = (response, etag) => {
|
|
125
|
+
response.setHeader(HeaderNames.ETag, etag);
|
|
126
|
+
};
|
|
127
|
+
const getETagValueFromIfMatch = (request) => {
|
|
128
|
+
const eTagValue = getETagFromIfMatch(request);
|
|
129
|
+
return isWeakETag(eTagValue) ? getWeakETagValue(eTagValue) : eTagValue;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/handler.ts
|
|
134
|
+
const on = (handle) => async (request, response, _next) => {
|
|
135
|
+
return (await Promise.resolve(handle(request)))(response);
|
|
136
|
+
};
|
|
137
|
+
const OK = (options) => (response) => {
|
|
138
|
+
send(response, 200, options);
|
|
139
|
+
};
|
|
140
|
+
const Created = (options) => (response) => {
|
|
141
|
+
sendCreated(response, options);
|
|
142
|
+
};
|
|
143
|
+
const Accepted = (options) => (response) => {
|
|
144
|
+
sendAccepted(response, options);
|
|
145
|
+
};
|
|
146
|
+
const NoContent = (options) => HttpResponse(204, options);
|
|
147
|
+
const HttpResponse = (statusCode, options) => (response) => {
|
|
148
|
+
send(response, statusCode, options);
|
|
149
|
+
};
|
|
150
|
+
const BadRequest = (options) => HttpProblem(400, options);
|
|
151
|
+
const Forbidden = (options) => HttpProblem(403, options);
|
|
152
|
+
const NotFound = (options) => HttpProblem(404, options);
|
|
153
|
+
const Conflict = (options) => HttpProblem(409, options);
|
|
154
|
+
const PreconditionFailed = (options) => HttpProblem(412, options);
|
|
155
|
+
const HttpProblem = (statusCode, options) => (response) => {
|
|
156
|
+
sendProblem(response, statusCode, options);
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/responses.ts
|
|
161
|
+
const DefaultHttpResponseOptions = {};
|
|
162
|
+
const DefaultHttpProblemResponseOptions = { problemDetails: "Error occured!" };
|
|
163
|
+
const sendCreated = (response, { eTag, ...options }) => send(response, 201, {
|
|
164
|
+
location: "url" in options ? options.url : `${response.req.url}/${options.createdId}`,
|
|
165
|
+
body: "createdId" in options ? {
|
|
166
|
+
id: options.createdId,
|
|
167
|
+
...options.body ?? {}
|
|
168
|
+
} : options.body,
|
|
169
|
+
eTag
|
|
1058
170
|
});
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
for (const requestFn of givenRequests) {
|
|
1109
|
-
await requestFn(_supertest2.default.call(void 0, application));
|
|
1110
|
-
}
|
|
1111
|
-
return setupRequest(_supertest2.default.call(void 0, application));
|
|
1112
|
-
};
|
|
1113
|
-
return {
|
|
1114
|
-
then: async (verify) => {
|
|
1115
|
-
const response = await handle();
|
|
1116
|
-
verify.forEach((assertion) => {
|
|
1117
|
-
const succeeded = assertion(response);
|
|
1118
|
-
if (succeeded === false) _assert2.default.fail();
|
|
1119
|
-
});
|
|
1120
|
-
}
|
|
1121
|
-
};
|
|
1122
|
-
}
|
|
1123
|
-
};
|
|
1124
|
-
};
|
|
171
|
+
const sendAccepted = (response, options) => send(response, 202, options);
|
|
172
|
+
const sendNoContent = (response, options) => send(response, 204, options);
|
|
173
|
+
const send = (response, statusCode, options) => {
|
|
174
|
+
const { location, body, eTag } = options ?? DefaultHttpResponseOptions;
|
|
175
|
+
if (eTag) setETag(response, eTag);
|
|
176
|
+
if (location) response.setHeader("Location", location);
|
|
177
|
+
if (body) {
|
|
178
|
+
response.statusCode = statusCode;
|
|
179
|
+
response.send(body);
|
|
180
|
+
} else response.sendStatus(statusCode);
|
|
181
|
+
};
|
|
182
|
+
const sendProblem = (response, statusCode, options) => {
|
|
183
|
+
options = options ?? DefaultHttpProblemResponseOptions;
|
|
184
|
+
const { location, eTag } = options;
|
|
185
|
+
const problemDetails = "problem" in options ? options.problem : new http_problem_details.ProblemDocument({
|
|
186
|
+
detail: options.problemDetails,
|
|
187
|
+
status: statusCode
|
|
188
|
+
});
|
|
189
|
+
if (eTag) setETag(response, eTag);
|
|
190
|
+
if (location) response.setHeader("Location", location);
|
|
191
|
+
response.setHeader("Content-Type", "application/problem+json");
|
|
192
|
+
response.statusCode = statusCode;
|
|
193
|
+
response.json(problemDetails);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
//#endregion
|
|
197
|
+
//#region src/testing/apiE2ESpecification.ts
|
|
198
|
+
function apiE2ESpecificationFor(optionsOrGetApplication, getApplication) {
|
|
199
|
+
const resolveApplication = () => {
|
|
200
|
+
if (typeof optionsOrGetApplication === "function" && getApplication) return getApplication(optionsOrGetApplication());
|
|
201
|
+
if (typeof optionsOrGetApplication !== "object") throw new _event_driven_io_emmett.EmmettError("Invalid arguments provided to apiE2ESpecificationFor. Expected either an options object or a getEventStore function and getApplication function.");
|
|
202
|
+
const eventStore = optionsOrGetApplication.getEventStore?.() ?? (0, _event_driven_io_emmett.getInMemoryEventStore)();
|
|
203
|
+
return optionsOrGetApplication.getApplication(eventStore);
|
|
204
|
+
};
|
|
205
|
+
return (...givenRequests) => {
|
|
206
|
+
const application = resolveApplication();
|
|
207
|
+
return { when: (setupRequest) => {
|
|
208
|
+
const handle = async () => {
|
|
209
|
+
for (const requestFn of givenRequests) await requestFn((0, supertest.default)(application));
|
|
210
|
+
return setupRequest((0, supertest.default)(application));
|
|
211
|
+
};
|
|
212
|
+
return { then: async (verify) => {
|
|
213
|
+
const response = await handle();
|
|
214
|
+
verify.forEach((assertion) => {
|
|
215
|
+
if (assertion(response) === false) assert.default.fail();
|
|
216
|
+
});
|
|
217
|
+
} };
|
|
218
|
+
} };
|
|
219
|
+
};
|
|
1125
220
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
};
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
if (succeeded === false) assertFails();
|
|
1184
|
-
}
|
|
1185
|
-
const events = typeof first === "function" ? rest : verify;
|
|
1186
|
-
assertMatches(
|
|
1187
|
-
Array.from(eventStore.appendedEvents.values()),
|
|
1188
|
-
events
|
|
1189
|
-
);
|
|
1190
|
-
}
|
|
1191
|
-
}
|
|
1192
|
-
};
|
|
1193
|
-
}
|
|
1194
|
-
};
|
|
1195
|
-
};
|
|
221
|
+
const ApiE2ESpecification = { for: apiE2ESpecificationFor };
|
|
222
|
+
|
|
223
|
+
//#endregion
|
|
224
|
+
//#region src/testing/apiSpecification.ts
|
|
225
|
+
const existingStream = (streamId, events) => {
|
|
226
|
+
return [streamId, events];
|
|
227
|
+
};
|
|
228
|
+
const expect = (streamId, events) => {
|
|
229
|
+
return [streamId, events];
|
|
230
|
+
};
|
|
231
|
+
const expectNewEvents = (streamId, events) => {
|
|
232
|
+
return [streamId, events];
|
|
233
|
+
};
|
|
234
|
+
const expectResponse = (statusCode, options) => (response) => {
|
|
235
|
+
const { body, headers } = options ?? {};
|
|
236
|
+
(0, _event_driven_io_emmett.assertEqual)(statusCode, response.statusCode, "Response code doesn't match");
|
|
237
|
+
if (body) (0, _event_driven_io_emmett.assertMatches)(response.body, body);
|
|
238
|
+
if (headers) (0, _event_driven_io_emmett.assertMatches)(response.headers, headers);
|
|
239
|
+
};
|
|
240
|
+
const expectError = (errorCode, problemDetails) => expectResponse(errorCode, problemDetails ? { body: problemDetails } : void 0);
|
|
241
|
+
function apiSpecificationFor(optionsOrGetEventStore, getApplication) {
|
|
242
|
+
const resolveStoreAndApplication = () => {
|
|
243
|
+
if (typeof optionsOrGetEventStore === "function") {
|
|
244
|
+
const eventStore = (0, _event_driven_io_emmett.WrapEventStore)(optionsOrGetEventStore());
|
|
245
|
+
return {
|
|
246
|
+
eventStore,
|
|
247
|
+
application: getApplication(eventStore)
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
const eventStore = (0, _event_driven_io_emmett.WrapEventStore)(optionsOrGetEventStore.getEventStore());
|
|
251
|
+
return {
|
|
252
|
+
eventStore,
|
|
253
|
+
application: optionsOrGetEventStore.getApplication(eventStore)
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
return (...givenStreams) => {
|
|
257
|
+
const { eventStore, application } = resolveStoreAndApplication();
|
|
258
|
+
return { when: (setupRequest) => {
|
|
259
|
+
const handle = async () => {
|
|
260
|
+
for (const [streamName, events] of givenStreams) await eventStore.setup(streamName, events);
|
|
261
|
+
return setupRequest((0, supertest.default)(application));
|
|
262
|
+
};
|
|
263
|
+
return { then: async (verify) => {
|
|
264
|
+
const response = await handle();
|
|
265
|
+
if (typeof verify === "function") {
|
|
266
|
+
if (verify(response) === false) (0, _event_driven_io_emmett.assertFails)();
|
|
267
|
+
} else if (Array.isArray(verify)) {
|
|
268
|
+
const [first, ...rest] = verify;
|
|
269
|
+
if (typeof first === "function") {
|
|
270
|
+
if (first(response) === false) (0, _event_driven_io_emmett.assertFails)();
|
|
271
|
+
}
|
|
272
|
+
const events = typeof first === "function" ? rest : verify;
|
|
273
|
+
(0, _event_driven_io_emmett.assertMatches)(Array.from(eventStore.appendedEvents.values()), events);
|
|
274
|
+
}
|
|
275
|
+
} };
|
|
276
|
+
} };
|
|
277
|
+
};
|
|
1196
278
|
}
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
exports.Accepted = Accepted; exports.ApiE2ESpecification = ApiE2ESpecification; exports.ApiSpecification = ApiSpecification; exports.BadRequest = BadRequest; exports.Conflict = Conflict; exports.Created = Created; exports.DefaultHttpProblemResponseOptions = DefaultHttpProblemResponseOptions; exports.DefaultHttpResponseOptions = DefaultHttpResponseOptions; exports.ETagErrors = ETagErrors; exports.Forbidden = Forbidden; exports.HeaderNames = HeaderNames; exports.HttpProblem = HttpProblem; exports.HttpResponse = HttpResponse; exports.NoContent = NoContent; exports.NotFound = NotFound; exports.OK = OK; exports.PreconditionFailed = PreconditionFailed; exports.WeakETagRegex = WeakETagRegex; exports.existingStream = existingStream; exports.expect = expect; exports.expectError = expectError; exports.expectNewEvents = expectNewEvents; exports.expectResponse = expectResponse; exports.getApplication = getApplication; exports.getETagFromIfMatch = getETagFromIfMatch; exports.getETagFromIfNotMatch = getETagFromIfNotMatch; exports.getETagValueFromIfMatch = getETagValueFromIfMatch; exports.getWeakETagValue = getWeakETagValue; exports.isWeakETag = isWeakETag; exports.on = on; exports.send = send; exports.sendAccepted = sendAccepted; exports.sendCreated = sendCreated; exports.sendNoContent = sendNoContent; exports.sendProblem = sendProblem; exports.setETag = setETag; exports.startAPI = startAPI; exports.toWeakETag = toWeakETag;
|
|
279
|
+
const ApiSpecification = { for: apiSpecificationFor };
|
|
280
|
+
|
|
281
|
+
//#endregion
|
|
282
|
+
exports.Accepted = Accepted;
|
|
283
|
+
exports.ApiE2ESpecification = ApiE2ESpecification;
|
|
284
|
+
exports.ApiSpecification = ApiSpecification;
|
|
285
|
+
exports.BadRequest = BadRequest;
|
|
286
|
+
exports.Conflict = Conflict;
|
|
287
|
+
exports.Created = Created;
|
|
288
|
+
exports.DefaultHttpProblemResponseOptions = DefaultHttpProblemResponseOptions;
|
|
289
|
+
exports.DefaultHttpResponseOptions = DefaultHttpResponseOptions;
|
|
290
|
+
exports.ETagErrors = ETagErrors;
|
|
291
|
+
exports.Forbidden = Forbidden;
|
|
292
|
+
exports.HeaderNames = HeaderNames;
|
|
293
|
+
exports.HttpProblem = HttpProblem;
|
|
294
|
+
exports.HttpResponse = HttpResponse;
|
|
295
|
+
exports.NoContent = NoContent;
|
|
296
|
+
exports.NotFound = NotFound;
|
|
297
|
+
exports.OK = OK;
|
|
298
|
+
exports.PreconditionFailed = PreconditionFailed;
|
|
299
|
+
exports.WeakETagRegex = WeakETagRegex;
|
|
300
|
+
exports.existingStream = existingStream;
|
|
301
|
+
exports.expect = expect;
|
|
302
|
+
exports.expectError = expectError;
|
|
303
|
+
exports.expectNewEvents = expectNewEvents;
|
|
304
|
+
exports.expectResponse = expectResponse;
|
|
305
|
+
exports.getApplication = getApplication;
|
|
306
|
+
exports.getETagFromIfMatch = getETagFromIfMatch;
|
|
307
|
+
exports.getETagFromIfNotMatch = getETagFromIfNotMatch;
|
|
308
|
+
exports.getETagValueFromIfMatch = getETagValueFromIfMatch;
|
|
309
|
+
exports.getWeakETagValue = getWeakETagValue;
|
|
310
|
+
exports.isWeakETag = isWeakETag;
|
|
311
|
+
exports.on = on;
|
|
312
|
+
exports.send = send;
|
|
313
|
+
exports.sendAccepted = sendAccepted;
|
|
314
|
+
exports.sendCreated = sendCreated;
|
|
315
|
+
exports.sendNoContent = sendNoContent;
|
|
316
|
+
exports.sendProblem = sendProblem;
|
|
317
|
+
exports.setETag = setETag;
|
|
318
|
+
exports.startAPI = startAPI;
|
|
319
|
+
exports.toWeakETag = toWeakETag;
|
|
1240
320
|
//# sourceMappingURL=index.cjs.map
|