feat: add peerDependencies
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
export abstract class ServiceError<TData = unknown> extends Error {
|
||||
constructor(message: string, readonly status: number, readonly data?: TData) {
|
||||
constructor(
|
||||
message: string,
|
||||
readonly status: number,
|
||||
readonly data?: TData,
|
||||
) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import z from "zod";
|
||||
import z from "zod/v4";
|
||||
|
||||
import { event } from "../../libraries/event.ts";
|
||||
import { EventFactory } from "../../libraries/event-factory.ts";
|
||||
@@ -11,7 +11,10 @@ export const events = new EventFactory([
|
||||
.data(
|
||||
z.strictObject({
|
||||
name: z
|
||||
.union([z.strictObject({ given: z.string(), family: z.string().optional() }), z.strictObject({ given: z.string().optional(), family: z.string() })])
|
||||
.union([
|
||||
z.strictObject({ given: z.string(), family: z.string().optional() }),
|
||||
z.strictObject({ given: z.string().optional(), family: z.string() }),
|
||||
])
|
||||
.optional(),
|
||||
email: z.string(),
|
||||
}),
|
||||
|
||||
@@ -2,10 +2,10 @@ import { afterAll, afterEach, beforeAll, describe } from "@std/testing/bdd";
|
||||
import { MongoTestContainer } from "@valkyr/testcontainers/mongodb";
|
||||
|
||||
import { MongoAdapter, register } from "../adapters/mongo/adapter.ts";
|
||||
import { EventStore, EventStoreHooks } from "../libraries/event-store.ts";
|
||||
import { EventStore, type EventStoreHooks } from "../libraries/event-store.ts";
|
||||
import { Projector } from "../libraries/projector.ts";
|
||||
import { aggregates } from "./mocks/aggregates.ts";
|
||||
import { events, EventStoreFactory } from "./mocks/events.ts";
|
||||
import { events, type EventStoreFactory } from "./mocks/events.ts";
|
||||
import testAddEvent from "./store/add-event.ts";
|
||||
import testAddManyEvents from "./store/add-many-events.ts";
|
||||
import testCreateSnapshot from "./store/create-snapshot.ts";
|
||||
@@ -38,7 +38,11 @@ beforeAll(async () => {
|
||||
|
||||
afterEach(async () => {
|
||||
const db = container.client.db(DB_NAME);
|
||||
await Promise.all([db.collection("events").deleteMany({}), db.collection("relations").deleteMany({}), db.collection("snapshots").deleteMany({})]);
|
||||
await Promise.all([
|
||||
db.collection("events").deleteMany({}),
|
||||
db.collection("relations").deleteMany({}),
|
||||
db.collection("snapshots").deleteMany({}),
|
||||
]);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
|
||||
@@ -26,7 +26,8 @@ const DB_NAME = "sandbox";
|
||||
const container = await PostgresTestContainer.start("postgres:17");
|
||||
const sql = postgres(container.url(DB_NAME));
|
||||
|
||||
const eventStoreFn = async (options: { hooks?: EventStoreHooks<EventStoreFactory> } = {}) => getEventStore(sql, options);
|
||||
const eventStoreFn = async (options: { hooks?: EventStoreHooks<EventStoreFactory> } = {}) =>
|
||||
getEventStore(sql, options);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
@@ -76,7 +77,9 @@ beforeAll(async () => {
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await container.client(DB_NAME)`TRUNCATE "event_store"."relations","event_store"."events","event_store"."snapshots" CASCADE`;
|
||||
await container.client(
|
||||
DB_NAME,
|
||||
)`TRUNCATE "event_store"."relations","event_store"."events","event_store"."snapshots" CASCADE`;
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -111,7 +114,10 @@ describe("Adapter > Postgres", () => {
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
async function getEventStore(connection: PostgresConnection, { hooks = {} }: { hooks?: EventStoreHooks<EventStoreFactory> }) {
|
||||
async function getEventStore(
|
||||
connection: PostgresConnection,
|
||||
{ hooks = {} }: { hooks?: EventStoreHooks<EventStoreFactory> },
|
||||
) {
|
||||
const store = new EventStore({
|
||||
adapter: new PostgresAdapter(connection, { schema: "event_store" }),
|
||||
events,
|
||||
|
||||
@@ -8,7 +8,11 @@ export default describe<EventStoreFactory>(".makeAggregateReducer", (getEventSto
|
||||
it("should reduce a user", async () => {
|
||||
const { store } = await getEventStore();
|
||||
|
||||
const userA = await store.aggregate("user").create({ given: "John", family: "Doe" }, "john.doe@fixture.none").setGivenName("Jane").save();
|
||||
const userA = await store
|
||||
.aggregate("user")
|
||||
.create({ given: "John", family: "Doe" }, "john.doe@fixture.none")
|
||||
.setGivenName("Jane")
|
||||
.save();
|
||||
|
||||
await userA.snapshot();
|
||||
|
||||
|
||||
@@ -82,7 +82,12 @@ export default describe<EventStoreFactory>(".makeReducer", (getEventStore) => {
|
||||
}),
|
||||
);
|
||||
|
||||
const state = await store.reduce({ name: "user", stream: streamA, reducer: userReducer, filter: { types: ["user:created", "user:email-set"] } });
|
||||
const state = await store.reduce({
|
||||
name: "user",
|
||||
stream: streamA,
|
||||
reducer: userReducer,
|
||||
filter: { types: ["user:created", "user:email-set"] },
|
||||
});
|
||||
|
||||
assertEquals(state?.name, { given: "John", family: "Doe" });
|
||||
assertEquals(state?.email, "jane.doe@fixture.none");
|
||||
@@ -100,10 +105,31 @@ export default describe<EventStoreFactory>(".makeReducer", (getEventStore) => {
|
||||
const post2 = makeId();
|
||||
const post3 = makeId();
|
||||
|
||||
await store.pushEvent(store.event({ stream: post1, type: "post:created", data: { title: "Post #1", body: "Sample #1" }, meta: { auditor } }));
|
||||
await store.pushEvent(store.event({ stream: post2, type: "post:created", data: { title: "Post #2", body: "Sample #2" }, meta: { auditor } }));
|
||||
await store.pushEvent(
|
||||
store.event({
|
||||
stream: post1,
|
||||
type: "post:created",
|
||||
data: { title: "Post #1", body: "Sample #1" },
|
||||
meta: { auditor },
|
||||
}),
|
||||
);
|
||||
await store.pushEvent(
|
||||
store.event({
|
||||
stream: post2,
|
||||
type: "post:created",
|
||||
data: { title: "Post #2", body: "Sample #2" },
|
||||
meta: { auditor },
|
||||
}),
|
||||
);
|
||||
await store.pushEvent(store.event({ stream: post2, type: "post:removed", meta: { auditor } }));
|
||||
await store.pushEvent(store.event({ stream: post3, type: "post:created", data: { title: "Post #3", body: "Sample #3" }, meta: { auditor } }));
|
||||
await store.pushEvent(
|
||||
store.event({
|
||||
stream: post3,
|
||||
type: "post:created",
|
||||
data: { title: "Post #3", body: "Sample #3" },
|
||||
meta: { auditor },
|
||||
}),
|
||||
);
|
||||
|
||||
const events = await store.getEventsByRelations([`user:${auditor}:posts`]);
|
||||
|
||||
|
||||
@@ -25,7 +25,10 @@ export default describe<EventStoreFactory>(".pushAggregate", (getEventStore) =>
|
||||
|
||||
assertEquals(records.length, 3);
|
||||
|
||||
assertObjectMatch(records[0], { stream: user.id, data: { name: { given: "Jane", family: "Doe" }, email: "jane.doe@fixture.none" } });
|
||||
assertObjectMatch(records[0], {
|
||||
stream: user.id,
|
||||
data: { name: { given: "Jane", family: "Doe" }, email: "jane.doe@fixture.none" },
|
||||
});
|
||||
assertObjectMatch(records[1], { stream: user.id, data: "John" });
|
||||
assertObjectMatch(records[2], { stream: user.id, data: "john.doe@fixture.none", meta: { auditor: "admin" } });
|
||||
|
||||
|
||||
@@ -33,10 +33,16 @@ export default describe<EventStoreFactory>(".pushManyAggregates", (getEventStore
|
||||
|
||||
assertEquals(records.length, 6);
|
||||
|
||||
assertObjectMatch(records[0], { stream: userA.id, data: { name: { given: "Jane", family: "Doe" }, email: "jane.doe@fixture.none" } });
|
||||
assertObjectMatch(records[0], {
|
||||
stream: userA.id,
|
||||
data: { name: { given: "Jane", family: "Doe" }, email: "jane.doe@fixture.none" },
|
||||
});
|
||||
assertObjectMatch(records[1], { stream: userA.id, data: "John" });
|
||||
assertObjectMatch(records[2], { stream: userA.id, data: "john.doe@fixture.none", meta: { auditor: "admin" } });
|
||||
assertObjectMatch(records[3], { stream: userB.id, data: { name: { given: "Peter", family: "Doe" }, email: "peter.doe@fixture.none" } });
|
||||
assertObjectMatch(records[3], {
|
||||
stream: userB.id,
|
||||
data: { name: { given: "Peter", family: "Doe" }, email: "peter.doe@fixture.none" },
|
||||
});
|
||||
assertObjectMatch(records[4], { stream: userB.id, data: "Barry" });
|
||||
assertObjectMatch(records[5], { stream: userB.id, data: "barry.doe@fixture.none", meta: { auditor: "admin" } });
|
||||
|
||||
|
||||
@@ -11,7 +11,9 @@ export function describe<TEventFactory extends EventFactory>(
|
||||
return (getEventStore: EventStoreFn<TEventFactory>) => desc(name, () => runner(getEventStore));
|
||||
}
|
||||
|
||||
type EventStoreFn<TEventFactory extends EventFactory> = (options?: { hooks?: EventStoreHooks<TEventFactory> }) => Promise<{
|
||||
type EventStoreFn<TEventFactory extends EventFactory> = (options?: {
|
||||
hooks?: EventStoreHooks<TEventFactory>;
|
||||
}) => Promise<{
|
||||
store: EventStore<TEventFactory, any, any>;
|
||||
projector: Projector<TEventFactory>;
|
||||
}>;
|
||||
|
||||
Reference in New Issue
Block a user