eventsourcingdb 1.8.2 → 1.8.3
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/Bound.d.ts +6 -0
- package/dist/Bound.js +1 -0
- package/dist/Client.d.ts +21 -0
- package/dist/Client.js +484 -0
- package/dist/CloudEvent.d.ts +16 -0
- package/dist/CloudEvent.js +1 -0
- package/dist/Container.d.ts +20 -0
- package/dist/Container.js +108 -0
- package/dist/Event.d.ts +36 -0
- package/dist/Event.js +63 -0
- package/dist/EventCandidate.d.ts +9 -0
- package/dist/EventCandidate.js +1 -0
- package/dist/EventType.d.ts +6 -0
- package/dist/EventType.js +1 -0
- package/dist/ObserveEventsOptions.d.ts +13 -0
- package/dist/ObserveEventsOptions.js +1 -0
- package/dist/Precondition.d.ts +27 -0
- package/dist/Precondition.js +1 -0
- package/dist/ReadEventsOptions.d.ts +16 -0
- package/dist/ReadEventsOptions.js +1 -0
- package/dist/convertCloudEventToEvent.d.ts +4 -0
- package/dist/convertCloudEventToEvent.js +18 -0
- package/dist/getImageVersionFromDockerfile.d.ts +2 -0
- package/dist/getImageVersionFromDockerfile.js +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +7 -0
- package/dist/isCloudEvent.d.ts +3 -0
- package/dist/isCloudEvent.js +21 -0
- package/dist/isEventQlQueryTrue.d.ts +3 -0
- package/dist/isEventQlQueryTrue.js +5 -0
- package/dist/isSubjectOnEventId.d.ts +3 -0
- package/dist/isSubjectOnEventId.js +5 -0
- package/dist/isSubjectPopulated.d.ts +3 -0
- package/dist/isSubjectPopulated.js +5 -0
- package/dist/isSubjectPristine.d.ts +3 -0
- package/dist/isSubjectPristine.js +5 -0
- package/dist/isValidServerHeader.d.ts +2 -0
- package/dist/isValidServerHeader.js +11 -0
- package/dist/ndjson/readNdJsonStream.d.ts +2 -0
- package/dist/ndjson/readNdJsonStream.js +43 -0
- package/dist/stream/StreamCloudEvent.d.ts +19 -0
- package/dist/stream/StreamCloudEvent.js +1 -0
- package/dist/stream/StreamError.d.ts +7 -0
- package/dist/stream/StreamError.js +1 -0
- package/dist/stream/StreamEventType.d.ts +9 -0
- package/dist/stream/StreamEventType.js +1 -0
- package/dist/stream/StreamHeartbeat.d.ts +4 -0
- package/dist/stream/StreamHeartbeat.js +1 -0
- package/dist/stream/StreamRow.d.ts +5 -0
- package/dist/stream/StreamRow.js +1 -0
- package/dist/stream/StreamSubject.d.ts +7 -0
- package/dist/stream/StreamSubject.js +1 -0
- package/dist/stream/isStreamCloudEvent.d.ts +3 -0
- package/dist/stream/isStreamCloudEvent.js +24 -0
- package/dist/stream/isStreamError.d.ts +3 -0
- package/dist/stream/isStreamError.js +9 -0
- package/dist/stream/isStreamEventType.d.ts +3 -0
- package/dist/stream/isStreamEventType.js +11 -0
- package/dist/stream/isStreamHeartbeat.d.ts +3 -0
- package/dist/stream/isStreamHeartbeat.js +5 -0
- package/dist/stream/isStreamRow.d.ts +3 -0
- package/dist/stream/isStreamRow.js +6 -0
- package/dist/stream/isStreamSubject.d.ts +3 -0
- package/dist/stream/isStreamSubject.js +9 -0
- package/dist/types/hasShapeOf.d.ts +6 -0
- package/dist/types/hasShapeOf.js +25 -0
- package/dist/types/isBoolean.d.ts +2 -0
- package/dist/types/isBoolean.js +7 -0
- package/dist/types/isRecord.d.ts +2 -0
- package/dist/types/isRecord.js +13 -0
- package/dist/types/isString.d.ts +2 -0
- package/dist/types/isString.js +7 -0
- package/dist/types/isStringOrNull.d.ts +2 -0
- package/dist/types/isStringOrNull.js +10 -0
- package/dist/types/isStringOrUndefined.d.ts +2 -0
- package/dist/types/isStringOrUndefined.js +10 -0
- package/package.json +13 -16
- package/.editorconfig +0 -22
- package/.nvmrc +0 -1
- package/dist/index.cjs +0 -3
- package/dist/index.d.cts +0 -182
- package/dist/index.d.mts +0 -182
- package/dist/index.mjs +0 -3
package/dist/Event.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
declare class Event {
|
|
3
|
+
#private;
|
|
4
|
+
specversion: string;
|
|
5
|
+
id: string;
|
|
6
|
+
time: Date;
|
|
7
|
+
source: string;
|
|
8
|
+
subject: string;
|
|
9
|
+
type: string;
|
|
10
|
+
datacontenttype: string;
|
|
11
|
+
data: Record<string, unknown>;
|
|
12
|
+
hash: string;
|
|
13
|
+
predecessorhash: string;
|
|
14
|
+
traceparent?: string;
|
|
15
|
+
tracestate?: string;
|
|
16
|
+
signature: string | null;
|
|
17
|
+
constructor({ specversion, id, time, timeFromServer, source, subject, type, datacontenttype, data, hash, predecessorhash, traceparent, tracestate, signature, }: {
|
|
18
|
+
specversion: string;
|
|
19
|
+
id: string;
|
|
20
|
+
time: Date;
|
|
21
|
+
timeFromServer: string;
|
|
22
|
+
source: string;
|
|
23
|
+
subject: string;
|
|
24
|
+
type: string;
|
|
25
|
+
datacontenttype: string;
|
|
26
|
+
data: Record<string, unknown>;
|
|
27
|
+
hash: string;
|
|
28
|
+
predecessorhash: string;
|
|
29
|
+
traceparent?: string;
|
|
30
|
+
tracestate?: string;
|
|
31
|
+
signature: string | null;
|
|
32
|
+
});
|
|
33
|
+
verifyHash(): void;
|
|
34
|
+
verifySignature(verificationKey: crypto.KeyObject): void;
|
|
35
|
+
}
|
|
36
|
+
export { Event };
|
package/dist/Event.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
class Event {
|
|
3
|
+
specversion;
|
|
4
|
+
id;
|
|
5
|
+
time;
|
|
6
|
+
#timeFromServer;
|
|
7
|
+
source;
|
|
8
|
+
subject;
|
|
9
|
+
type;
|
|
10
|
+
datacontenttype;
|
|
11
|
+
data;
|
|
12
|
+
hash;
|
|
13
|
+
predecessorhash;
|
|
14
|
+
traceparent;
|
|
15
|
+
tracestate;
|
|
16
|
+
signature;
|
|
17
|
+
constructor({ specversion, id, time, timeFromServer, source, subject, type, datacontenttype, data, hash, predecessorhash, traceparent, tracestate, signature, }) {
|
|
18
|
+
this.specversion = specversion;
|
|
19
|
+
this.id = id;
|
|
20
|
+
this.time = time;
|
|
21
|
+
this.#timeFromServer = timeFromServer;
|
|
22
|
+
this.source = source;
|
|
23
|
+
this.subject = subject;
|
|
24
|
+
this.type = type;
|
|
25
|
+
this.datacontenttype = datacontenttype;
|
|
26
|
+
this.data = data;
|
|
27
|
+
this.hash = hash;
|
|
28
|
+
this.predecessorhash = predecessorhash;
|
|
29
|
+
this.traceparent = traceparent;
|
|
30
|
+
this.tracestate = tracestate;
|
|
31
|
+
this.signature = signature;
|
|
32
|
+
}
|
|
33
|
+
verifyHash() {
|
|
34
|
+
const metadata = `${this.specversion}|${this.id}|${this.predecessorhash}|${this.#timeFromServer}|${this.source}|${this.subject}|${this.type}|${this.datacontenttype}`;
|
|
35
|
+
const metadataHash = crypto.createHash('sha256').update(metadata).digest('hex');
|
|
36
|
+
const dataHash = crypto.createHash('sha256').update(JSON.stringify(this.data)).digest('hex');
|
|
37
|
+
const finalHash = crypto
|
|
38
|
+
.createHash('sha256')
|
|
39
|
+
.update(`${metadataHash}${dataHash}`)
|
|
40
|
+
.digest('hex');
|
|
41
|
+
if (finalHash !== this.hash) {
|
|
42
|
+
throw new Error('Failed to verify hash.');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
verifySignature(verificationKey) {
|
|
46
|
+
if (this.signature === null) {
|
|
47
|
+
throw new Error('Signature must not be null.');
|
|
48
|
+
}
|
|
49
|
+
this.verifyHash();
|
|
50
|
+
const signaturePrefix = 'esdb:signature:v1:';
|
|
51
|
+
if (!this.signature.startsWith(signaturePrefix)) {
|
|
52
|
+
throw new Error(`Signature must start with '${signaturePrefix}'`);
|
|
53
|
+
}
|
|
54
|
+
const signature = this.signature.slice(signaturePrefix.length);
|
|
55
|
+
const signatureBytes = Buffer.from(signature, 'hex');
|
|
56
|
+
const hashBytes = Buffer.from(this.hash, 'utf8');
|
|
57
|
+
const isSignatureValid = crypto.verify(null, hashBytes, verificationKey, signatureBytes);
|
|
58
|
+
if (!isSignatureValid) {
|
|
59
|
+
throw new Error('Signature verification failed.');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export { Event };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Bound } from './Bound.js';
|
|
2
|
+
type ObserveIfEventIsMissing = 'read-everything' | 'wait-for-event';
|
|
3
|
+
interface ObserveFromLatestEvent {
|
|
4
|
+
subject: string;
|
|
5
|
+
type: string;
|
|
6
|
+
ifEventIsMissing: ObserveIfEventIsMissing;
|
|
7
|
+
}
|
|
8
|
+
interface ObserveEventsOptions {
|
|
9
|
+
recursive: boolean;
|
|
10
|
+
lowerBound?: Bound;
|
|
11
|
+
fromLatestEvent?: ObserveFromLatestEvent;
|
|
12
|
+
}
|
|
13
|
+
export type { ObserveEventsOptions, ObserveFromLatestEvent, ObserveIfEventIsMissing };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
interface IsSubjectPristinePrecondition {
|
|
2
|
+
subject: string;
|
|
3
|
+
}
|
|
4
|
+
interface IsSubjectPopulatedPrecondition {
|
|
5
|
+
subject: string;
|
|
6
|
+
}
|
|
7
|
+
interface IsSubjectOnEventIdPrecondition {
|
|
8
|
+
subject: string;
|
|
9
|
+
eventId: string;
|
|
10
|
+
}
|
|
11
|
+
interface IsEventQlQueryTruePrecondition {
|
|
12
|
+
query: string;
|
|
13
|
+
}
|
|
14
|
+
type Precondition = {
|
|
15
|
+
type: 'isSubjectPristine';
|
|
16
|
+
payload: IsSubjectPristinePrecondition;
|
|
17
|
+
} | {
|
|
18
|
+
type: 'isSubjectOnEventId';
|
|
19
|
+
payload: IsSubjectOnEventIdPrecondition;
|
|
20
|
+
} | {
|
|
21
|
+
type: 'isSubjectPopulated';
|
|
22
|
+
payload: IsSubjectPopulatedPrecondition;
|
|
23
|
+
} | {
|
|
24
|
+
type: 'isEventQlQueryTrue';
|
|
25
|
+
payload: IsEventQlQueryTruePrecondition;
|
|
26
|
+
};
|
|
27
|
+
export type { Precondition };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Bound } from './Bound.js';
|
|
2
|
+
type Order = 'chronological' | 'antichronological';
|
|
3
|
+
type ReadIfEventIsMissing = 'read-nothing' | 'read-everything';
|
|
4
|
+
interface ReadFromLatestEvent {
|
|
5
|
+
subject: string;
|
|
6
|
+
type: string;
|
|
7
|
+
ifEventIsMissing: ReadIfEventIsMissing;
|
|
8
|
+
}
|
|
9
|
+
interface ReadEventsOptions {
|
|
10
|
+
recursive: boolean;
|
|
11
|
+
order?: Order;
|
|
12
|
+
lowerBound?: Bound;
|
|
13
|
+
upperBound?: Bound;
|
|
14
|
+
fromLatestEvent?: ReadFromLatestEvent;
|
|
15
|
+
}
|
|
16
|
+
export type { Order, ReadEventsOptions, ReadFromLatestEvent, ReadIfEventIsMissing };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Event } from './Event.js';
|
|
2
|
+
const convertCloudEventToEvent = (cloudEvent) => new Event({
|
|
3
|
+
specversion: cloudEvent.specversion,
|
|
4
|
+
id: cloudEvent.id,
|
|
5
|
+
time: new Date(cloudEvent.time),
|
|
6
|
+
timeFromServer: cloudEvent.time,
|
|
7
|
+
source: cloudEvent.source,
|
|
8
|
+
subject: cloudEvent.subject,
|
|
9
|
+
type: cloudEvent.type,
|
|
10
|
+
datacontenttype: cloudEvent.datacontenttype,
|
|
11
|
+
data: cloudEvent.data,
|
|
12
|
+
hash: cloudEvent.hash,
|
|
13
|
+
predecessorhash: cloudEvent.predecessorhash,
|
|
14
|
+
traceparent: cloudEvent.traceparent,
|
|
15
|
+
tracestate: cloudEvent.tracestate,
|
|
16
|
+
signature: cloudEvent.signature,
|
|
17
|
+
});
|
|
18
|
+
export { convertCloudEventToEvent };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const versionRegex = /^FROM\sthenativeweb\/eventsourcingdb:(.+)$/mu;
|
|
4
|
+
const getImageVersionFromDockerfile = () => {
|
|
5
|
+
const dockerfile = path.join(import.meta.dirname, '..', 'docker', 'Dockerfile');
|
|
6
|
+
const data = fs.readFileSync(dockerfile, 'utf-8');
|
|
7
|
+
const matches = data.match(versionRegex);
|
|
8
|
+
const version = matches?.[1];
|
|
9
|
+
if (version === undefined) {
|
|
10
|
+
throw new Error('Failed to find image version in Dockerfile.');
|
|
11
|
+
}
|
|
12
|
+
return version;
|
|
13
|
+
};
|
|
14
|
+
export { getImageVersionFromDockerfile };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Client } from './Client.js';
|
|
2
|
+
import { Container } from './Container.js';
|
|
3
|
+
import type { Event } from './Event.js';
|
|
4
|
+
import type { EventCandidate } from './EventCandidate.js';
|
|
5
|
+
import type { EventType } from './EventType.js';
|
|
6
|
+
import { isEventQlQueryTrue } from './isEventQlQueryTrue.js';
|
|
7
|
+
import { isSubjectOnEventId } from './isSubjectOnEventId.js';
|
|
8
|
+
import { isSubjectPopulated } from './isSubjectPopulated.js';
|
|
9
|
+
import { isSubjectPristine } from './isSubjectPristine.js';
|
|
10
|
+
import type { ObserveEventsOptions } from './ObserveEventsOptions.js';
|
|
11
|
+
import type { Precondition } from './Precondition.js';
|
|
12
|
+
import type { ReadEventsOptions } from './ReadEventsOptions.js';
|
|
13
|
+
export type { Event, EventCandidate, EventType, ObserveEventsOptions, Precondition, ReadEventsOptions, };
|
|
14
|
+
export { Client, Container, isEventQlQueryTrue, isSubjectOnEventId, isSubjectPopulated, isSubjectPristine, };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Client } from './Client.js';
|
|
2
|
+
import { Container } from './Container.js';
|
|
3
|
+
import { isEventQlQueryTrue } from './isEventQlQueryTrue.js';
|
|
4
|
+
import { isSubjectOnEventId } from './isSubjectOnEventId.js';
|
|
5
|
+
import { isSubjectPopulated } from './isSubjectPopulated.js';
|
|
6
|
+
import { isSubjectPristine } from './isSubjectPristine.js';
|
|
7
|
+
export { Client, Container, isEventQlQueryTrue, isSubjectOnEventId, isSubjectPopulated, isSubjectPristine, };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { hasShapeOf } from './types/hasShapeOf.js';
|
|
2
|
+
import { isRecord } from './types/isRecord.js';
|
|
3
|
+
import { isString } from './types/isString.js';
|
|
4
|
+
import { isStringOrNull } from './types/isStringOrNull.js';
|
|
5
|
+
import { isStringOrUndefined } from './types/isStringOrUndefined.js';
|
|
6
|
+
const isCloudEvent = (value) => hasShapeOf(value, {
|
|
7
|
+
specversion: isString,
|
|
8
|
+
id: isString,
|
|
9
|
+
time: isString,
|
|
10
|
+
source: isString,
|
|
11
|
+
subject: isString,
|
|
12
|
+
type: isString,
|
|
13
|
+
datacontenttype: isString,
|
|
14
|
+
data: isRecord,
|
|
15
|
+
hash: isString,
|
|
16
|
+
predecessorhash: isString,
|
|
17
|
+
traceparent: isStringOrUndefined,
|
|
18
|
+
tracestate: isStringOrUndefined,
|
|
19
|
+
signature: isStringOrNull,
|
|
20
|
+
});
|
|
21
|
+
export { isCloudEvent };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const isValidServerHeader = (response) => {
|
|
2
|
+
const serverHeader = response.headers.get('Server');
|
|
3
|
+
if (!serverHeader) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
if (!serverHeader.startsWith('EventSourcingDB/')) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
return true;
|
|
10
|
+
};
|
|
11
|
+
export { isValidServerHeader };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const readNdJsonStream = async function* (stream, signal) {
|
|
2
|
+
const reader = stream.getReader();
|
|
3
|
+
const decoder = new TextDecoder('utf-8');
|
|
4
|
+
let buffer = '';
|
|
5
|
+
const onAbort = () => {
|
|
6
|
+
reader.cancel().catch(() => {
|
|
7
|
+
// Intentionally left blank.
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
if (signal.aborted) {
|
|
11
|
+
await reader.cancel().catch(() => {
|
|
12
|
+
// Intentionally left blank.
|
|
13
|
+
});
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
signal.addEventListener('abort', onAbort);
|
|
17
|
+
try {
|
|
18
|
+
while (!signal.aborted) {
|
|
19
|
+
// biome-ignore lint/performance/noAwaitInLoops: Awaiting the result is fine here, although we are in a loop.
|
|
20
|
+
const { done, value } = await reader.read();
|
|
21
|
+
if (done) {
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
buffer += decoder.decode(value, { stream: true });
|
|
25
|
+
let index = buffer.indexOf('\n');
|
|
26
|
+
while (index !== -1) {
|
|
27
|
+
const line = buffer.slice(0, index).trim();
|
|
28
|
+
buffer = buffer.slice(index + 1);
|
|
29
|
+
if (line) {
|
|
30
|
+
yield JSON.parse(line);
|
|
31
|
+
}
|
|
32
|
+
index = buffer.indexOf('\n');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
signal.removeEventListener('abort', onAbort);
|
|
38
|
+
await reader.cancel().catch(() => {
|
|
39
|
+
// Intentionally left blank.
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
export { readNdJsonStream };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface StreamCloudEvent {
|
|
2
|
+
type: 'event';
|
|
3
|
+
payload: {
|
|
4
|
+
specversion: string;
|
|
5
|
+
id: string;
|
|
6
|
+
time: string;
|
|
7
|
+
source: string;
|
|
8
|
+
subject: string;
|
|
9
|
+
type: string;
|
|
10
|
+
datacontenttype: string;
|
|
11
|
+
data: Record<string, unknown>;
|
|
12
|
+
hash: string;
|
|
13
|
+
predecessorhash: string;
|
|
14
|
+
traceparent?: string;
|
|
15
|
+
tracestate?: string;
|
|
16
|
+
signature: string | null;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export type { StreamCloudEvent };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { hasShapeOf } from '../types/hasShapeOf.js';
|
|
2
|
+
import { isRecord } from '../types/isRecord.js';
|
|
3
|
+
import { isString } from '../types/isString.js';
|
|
4
|
+
import { isStringOrNull } from '../types/isStringOrNull.js';
|
|
5
|
+
import { isStringOrUndefined } from '../types/isStringOrUndefined.js';
|
|
6
|
+
const isStreamCloudEvent = (line) => hasShapeOf(line, {
|
|
7
|
+
type: (value) => value === 'event',
|
|
8
|
+
payload: {
|
|
9
|
+
specversion: isString,
|
|
10
|
+
id: isString,
|
|
11
|
+
time: isString,
|
|
12
|
+
source: isString,
|
|
13
|
+
subject: isString,
|
|
14
|
+
type: isString,
|
|
15
|
+
datacontenttype: isString,
|
|
16
|
+
data: isRecord,
|
|
17
|
+
hash: isString,
|
|
18
|
+
predecessorhash: isString,
|
|
19
|
+
traceparent: isStringOrUndefined,
|
|
20
|
+
tracestate: isStringOrUndefined,
|
|
21
|
+
signature: isStringOrNull,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
export { isStreamCloudEvent };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { hasShapeOf } from '../types/hasShapeOf.js';
|
|
2
|
+
import { isString } from '../types/isString.js';
|
|
3
|
+
const isStreamError = (line) => hasShapeOf(line, {
|
|
4
|
+
type: (value) => value === 'error',
|
|
5
|
+
payload: {
|
|
6
|
+
error: isString,
|
|
7
|
+
},
|
|
8
|
+
});
|
|
9
|
+
export { isStreamError };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { hasShapeOf } from '../types/hasShapeOf.js';
|
|
2
|
+
import { isBoolean } from '../types/isBoolean.js';
|
|
3
|
+
import { isString } from '../types/isString.js';
|
|
4
|
+
const isStreamEventType = (line) => hasShapeOf(line, {
|
|
5
|
+
type: (value) => value === 'eventType',
|
|
6
|
+
payload: {
|
|
7
|
+
eventType: isString,
|
|
8
|
+
isPhantom: isBoolean,
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
export { isStreamEventType };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { hasShapeOf } from '../types/hasShapeOf.js';
|
|
2
|
+
import { isString } from '../types/isString.js';
|
|
3
|
+
const isStreamSubject = (line) => hasShapeOf(line, {
|
|
4
|
+
type: (value) => value === 'subject',
|
|
5
|
+
payload: {
|
|
6
|
+
subject: isString,
|
|
7
|
+
},
|
|
8
|
+
});
|
|
9
|
+
export { isStreamSubject };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isRecord } from './isRecord.js';
|
|
2
|
+
const hasShapeOf = (value, shape) => {
|
|
3
|
+
if (!isRecord(value)) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
for (const key of Object.keys(shape)) {
|
|
7
|
+
const spec = shape[key];
|
|
8
|
+
const val = value[key];
|
|
9
|
+
if (typeof spec === 'function') {
|
|
10
|
+
const guard = spec;
|
|
11
|
+
if (!guard(val)) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (!isRecord(val)) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
if (!hasShapeOf(val, spec)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
};
|
|
25
|
+
export { hasShapeOf };
|